在进行flutter开发的过程中,有时也会引入H5页面。在H5页面获取的结果需要在dart页面中进行处理,这时就需要进行交互。
在这里推荐一个第三方SDK:flutter_inappwebview(https://pub-web.flutter-io.cn/packages/flutter_inappwebview),本文介绍的web通信也是依赖这个SDK实现的。
1. 引入第三方SDK
flutter_inappwebview: ^6.0.0
我这里使用的是6.0.0版本,实际使用需要根据flutter开发版本确定。可以打开如下链接查看SDK说明。flutter_inappwebview | Flutter packageA Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
https://pub-web.flutter-io.cn/packages/flutter_inappwebview
2. 在dart页面添加addJavaScriptHandler处理
onWebViewCreated: (controller) {
_controller = controller;
controller.addJavaScriptHandler(
handlerName: 'submitDataHandler',
callback: (args) async {
// args 是一个包含 JS 传过来的数据的 List
final data = args[0]; // 我们传的是一个对象
String testStr = data['testStr'];
LogD("✅ Flutter 接收到数据:$testStr");
// 在这里可以进行你的逻辑处理,例如调用你的 API 或者数据库操作等
},
);
},
核心代码也是很简单的,主要是添加一个addJavaScriptHandler处理,handlerName属性可以自定义名称。文章末尾会附上完整的dart页面代码。
3.在web页面发送消息
document.getElementById('submit-btn').addEventListener('click', function () {
const message = {
testStr: "Flutter 通信测试",
};
// 👇 向 Flutter 发送消息
if (window.flutter_inappwebview) {
window.flutter_inappwebview.callHandler('submitDataHandler', message);
} else {
console.warn("❗window.flutter_inappwebview 未定义,Flutter 通信失败");
}
return;
}
);
message是我们需要传给flutter的内容,submitDataHandler是在dart页面的handlerName属性内容。这里要和dart保持一致,否则名称不一样无法接收。
4.完整dart代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
class _WebTestHome extends StatefulWidget {
const _WebTestHome();
@override
State<_WebTestHome> createState() => _WebTestPageState();
}
class _WebTestPageState extends State<_WebTestHome> {
InAppWebViewController? _controller;
String? htmlContent;
@override
void initState() {
super.initState();
loadHtmlFromAssets();
}
@override
void dispose() {
if (_controller != null) _controller!.dispose();
super.dispose();
}
Future<void> loadHtmlFromAssets() async {
String content =
await rootBundle.loadString('assets/html/test.html');
setState(() {
htmlContent = content;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('问卷调查'),
centerTitle: true,
),
body: htmlContent == null
? const Center(child: CircularProgressIndicator())
: InAppWebView(
initialData: InAppWebViewInitialData(
data: htmlContent!,
baseUrl: WebUri("http://localhost/assets/html/"),
encoding: "utf-8",
mimeType: "text/html",
),
onWebViewCreated: (controller) {
_controller = controller;
controller.addJavaScriptHandler(
handlerName: 'submitDataHandler',
callback: (args) async {
// args 是一个包含 JS 传过来的数据的 List
final data = args[0]; // 我们传的是一个对象
String testStr = data['testStr'];
print("✅ Flutter 接收到数据:$testStr");
// 在这里可以进行你的逻辑处理,例如调用你的 API 或者数据库操作等
},
);
},
),
);
}
}
我引用的是本地的HTML文件,如果想要加载一个远程链接,可以将initialData替换为如下代码。
initialUrlRequest: URLRequest(
url: WebUri('https://www.baidu.com/'), // 这里替换为你想要加载的链接
),
文章写的比较粗俗,如果有什么建议和看法欢迎在评论区留言。
775

被折叠的 条评论
为什么被折叠?



