1. flutter webview插件选择
目前flutter的webview常用库有flutter_webview_plugins、webview_flutter,这里我选择的是webview_flutter
理由:webview_flutter是官方维护的插件,而且通过实践发现,webview_flutter与原生组件嵌套结合更友好,再一个我发现使用flutter_webview_plugins加载webview后在IOS端无法使用手势侧滑返回上一页
所以我选择webview_flutter来加载网页
2. 引入webview_flutter
// 在pubspec.yaml中添加依赖
webview_flutter: 0.3.22+1
// 在需要的地方导入包
import 'package:webview_flutter/webview_flutter.dart';
// 在iOS,需要在info.plist中添加
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
3. flutter的webview如何与js交互
final Completer<WebViewController> _webController = Completer<WebViewController>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
WebView(
// h5页面的地址
initialUrl: 'https://test.com/article-detail.html',
// JS执行模式, 允许JS执行
javascriptMode: JavascriptMode.unrestricted,
// hh5可以根据navigator.userAgent判断当前环境
userAgent: 'FlutterApp',
// 在WebView创建完成后调用,只会被调用一次
onWebViewCreated: (WebViewController webController) {
// 获取到WebViewController实例
_webController.complete(webController);
},
// WebView加载完毕时的回调
onPageFinished: (String url) {
// flutter调用js
_webController.future.then((controller){
var name = 'test'; // 方法名
var data = 'hello'; // 传递的参数
controller.evaluateJavascript("$name('$data')");
});
},
// js调用flutter
javascriptChannels: <JavascriptChannel>[
JavascriptChannel(
name: 'hide_loading', // 需要与h5一致
onMessageReceived: (JavascriptMessage msg) {
// print("参数: ${msg.message}");
// 关闭骨架屏加载效果
setState(() {
loading = false;
});
}
),
].toSet(),
),
// 骨架屏加载
Visibility(
visible: loading,
child: SkeletonPage()
)
]
);
);
}
- 上面我们在 Flutter 端通过 WebViewController 的 evaluateJavascript 方法进行js的调用,js方法名为test,同时传递参数hello,参数只能是字符串类型(h5调flutter传递参数也只能是字符串)
// 定义js方法给flutter调用
<script>
function test(param) {
console.log(param) // 'hello'
}
</script>
// js调用flutter
<button onclick="hideLoading">关闭loading</button>
<script>
function hideLoading() {
window['hide_loading'].postMessage('hello')
}
</script>
4. 关键点,在vue里面,需要把方法暴露给window,这样flutter才能调用
mounted() {
window.test = this.test
}
methods: {
test(param) {
console.log(param) // 'hello'
}
}