一、webview_flutter h5页面嵌入
flutter pub add webview_flutter
1 基础使用
void initState() {
late final PlatformWebViewControllerCreationParams params;
// 苹果安卓适配
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
);
} else {
params = const PlatformWebViewControllerCreationParams();
}
webViewController = WebViewController.fromPlatformCreationParams(params);
webViewController
..setJavaScriptMode(JavaScriptMode.unrestricted) //开启js,必须
..addJavaScriptChannel( //注册管道
'Resize',
onMessageReceived: (JavaScriptMessage message) async {
print('5555${message.message}');
},
)
..setBackgroundColor(const Color(0x00000000))//设置背景
..setNavigationDelegate(NavigationDelegate( //html页面生命周期
onProgress: (int progress) { //进度
debugPrint('WebView is loading (progress : $progress%)');
},
onPageStarted: (String url) { //开始加载
debugPrint('Page started loading: $url');
},
onWebResourceError: (e) { //加载状态错误之类
debugPrint('onWebResourceError: $e');
},
onPageFinished: (String url) { //加载完成
webViewController.runJavaScript(
'window.postMessage({"id":"${Get.arguments.id}","url":"${Config.BaseUrl}"});');
},
));
}
Widget 组件 使用future 异步加载
Widget build(BuildContext context) {
return FutureBuilder(
// 异步方法
future: searchNovelFromWeb(), //加载方法
builder: (context, snapshot) {
// 等待状态显示的widget
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
// 错误时显示的widget
} else if (snapshot.hasError) {
return const Text('Error');
} else {
return snapshot.data ?? const Text('No data');
}
});
}
四种加载方式
webViewController.loadHtmlString(html) 字符串加载编码容易出错
webViewController.loadRequest("http://www.baidu.com" ) 请求地址
webViewController.loadFile(absoluteFilePath) 加载文件,文件不会会随包一起发布
webViewController.loadFlutterAsset 异步加载文件,文件会随包一起发布
Future<Widget> searchNovelFromWeb() async {
Widget res;
try {
通过 webViewController.loadHtmlString(html) 配合使用
// String htmlData = await rootBundle.loadString('lib/assets/html/index.js');
// await webViewController.loadFlutterAsset('lib/assets/html/index.js') ;
// String html =
// await rootBundle.loadString('lib/assets/html/index.html');
// String localHtmlFilePath = Uri.dataFromString(
// html,
// mimeType: 'text/html',
// encoding: Encoding.getByName('utf-8'),
// ).toString();
// webViewController.loadHtmlString(html)
await webViewController.loadFlutterAsset(
'lib/assets/html/index.html',
);
res = WebViewWidget(controller: webViewController);
} catch (error) {
res = Text("加载失败:${error.toString()}");
print("加载失败:${error.toString()}");
}
return res;
}
2 flutter 与h5 通信
flutter向H5传参
//在flutter 中的web页面,可在onPageFinished中向H5进行传参
onPageFinished: (String url) async {
webViewController.runJavaScript( //直接穿第一个JSON对象
'window.postMessage({"id":"${Get.arguments.id}","url":"${Config.BaseUrl}"});');
},
},
//H5端接收参数,可在mounted中声明使用
window.addEventListener('message', (event) => {//这里接收的就是一个对象
console.log('Received data from Flutter:',event.data);
});
H5向flutter传参
//flutter 端 addJavaScriptChannel注册监听消息管道
webViewController..addJavaScriptChannel(
'Resize',
onMessageReceived: (JavaScriptMessage message) async {
print('5555${message.message}');
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text(message.message)),
// );
},
)
h5 端 利用postMessage传递
Toaster.postMessage('Hello Flutter!');