Flutter嵌入webview并与vue进行双向通信
Flutter嵌入webview并与vue进行双向通信最近在做一个将h5嵌入flutter中的项目,特此记录一下,如有不对之处,希望大家多多指正。本篇将围绕以下两点:插件的选择与使用flutter与vue之间的双向通信一、插件的选择与使用目前flutter使用的比较多webview插件的主要有以下三个:官方插件:webview_flutterflutter_webview_pluginflutte
Flutter嵌入webview并与vue进行双向通信
最近在做一个将h5嵌入flutter中的项目,特此记录一下,如有不对之处,希望大家多多指正。
本篇将围绕以下两点:
- 插件的选择与使用
- flutter与vue之间的双向通信
一、插件的选择与使用
目前flutter使用的比较多webview插件的主要有以下三个:
- webview_flutter(官方维护)
- flutter_webview_plugin(社区维护)
- flutter_inappbrowser(个人维护)
在插件的选择过程中,我主要比较了webview_flutter和flutter_webview_plugin。
首先看看webview_flutter提供的webview组件的构造函数:
WebView({
Key key,
this.onWebViewCreated, //WebView创建完成之后的回调
this.initialUrl, //初始化 URL
this.javascriptMode = JavascriptMode.disabled, //JS执行模式,默认是不调用
this.javascriptChannels, //JS可以调用Flutter 的通道
this.navigationDelegate, //路由委托,可以使用它执行拦截操作
this.gestureRecognizers, //手势相关
this.onPageStarted, //开始加载页面回调
this.onPageFinished, //页面加载完成的回调
this.onWebResourceError, //资源加载失败回调
this.debuggingEnabled = false,
this.gestureNavigationEnabled = false,
this.userAgent, //用户代理
this.initialMediaPlaybackPolicy =
AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
})
作为官方提供的插件,webview_flutter还是相对比较好用的,不过在开发的过程中发现其在国内某些品牌的手机上运行时,由于国内厂商对键盘进行魔改(比如安全键盘),会出现无发调出或者虚拟键盘闪烁后崩溃的问题,详情见官方issue。
再看flutter_webview_plugin,其提供的WebviewScaffold组件构造函数如下:
WebviewScaffold({
Key key,
this.appBar,
@required this.url, //String 加载的URL
this.headers, //添加头部
this.withJavascript, //bool 是否开启Javascript
this.clearCache, //bool 清理缓存
this.clearCookies, //bool 清理cookies
this.enableAppScheme,
this.userAgent, //String userAgent
this.primary = true,
this.persistentFooterButtons,
this.bottomNavigationBar, //Widget 底部的bar
this.withZoom, //bool 是否允许缩放
this.withLocalStorage, //bool 是否开启本地缓存
this.withLocalUrl, //bool
this.scrollBar, //bool 是否显示scrollBar
this.supportMultipleWindows,
this.appCacheEnabled, //bool 是否开启缓存
this.hidden = false, //bool 是否隐藏
this.initialChild, //初始化的child,如果hidden = true 显示Widget
this.allowFileURLs, //bool 是否允许请求本地的FileURL
this.resizeToAvoidBottomInset = false,
this.invalidUrlRegex,
this.geolocationEnabled
this.debuggingEnabled = false,
this.ignoreSSLErrors = false,
})
flutter_webview_plugin目前是由Flutter社区进行维护,易用程度目前高于webview_flutter 。特性是基于原生 WebView 封装的 Flutter 插件,将原生的一些基本使用 API 封装好提供给 Flutter 调用,因此并不能内嵌于 Flutter Widget 树中。
在比较两个插件的优劣之后,我在项目中选择了flutter_webview_plugin进行开发。
简单用法如下:
Flutter代码
class Webview extends StatefulWidget {
@override
WebViewState createState() => WebViewState();
}
class WebViewState extends State<Webview> {
var _resultInfo = 'Hello,Vue!';
FlutterWebviewPlugin flutterWebViewPlugin = new FlutterWebviewPlugin();
@override
Widget build(BuildContext context) {
return WebviewScaffold(
//要打开的网址,此处以百度为例
url: 'https://www.baidu.com/',
javascriptChannels: <JavascriptChannel>[
JavascriptChannel(
name: 'getInfoFromVue',
onMessageReceived: (JavascriptMessage message) {
print("收到的参数传入:" + message.message); //String Hello,Flutter
//通过evalJavascript()方法调用vue挂载到window的方法
flutterWebViewPlugin
.evalJavascript("window.getInfoFromFlutter('$_resultInfo')")
.then((result) {})
.catchError((onError) {});
}),
].toSet(),
);
}
}
JavascriptChannel里的name需要和web端约定好,前端开发通过约定好的name,比如此处的getInfoFromVue,调用postMessage()方法向Flutter传递参数。
Vue代码:
<template>
<div>
获取到的Flutter传入信息: <span>{{ infoFromFlutter }}</span>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "flutter",
data: function() {
return {
infoFromFlutter: "",
};
},
mounted: function() {
//将getInfoFromFlutter()方法挂载到window以供给Flutter调用
window["getInfoFromFlutter"] = info => {
this.getInfoFromFlutter(info);
};
getInfoFromVue.postMessage("Hello,Flutter");
},
methods: {
getInfoFromFlutter(info) {
this.infoFromFlutter = info;
}
}
};
</script>
最后,在Widget销毁之前将flutterWebViewPlugin 销毁掉。
@override
void dispose() {
flutterWebViewPlugin.dispose();
super.dispose();
}
更多推荐
所有评论(0)