启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情
Flutter系列文章列表
- 2022年了,你还不会flutter!!!
- Flutter 第一课---flutter特点及组件开发
- Flutter 第二课---组件生命周期和App生命周期
- Flutter 第三课---状态管理之Provide
- Flutter 第四课---路由管理
- Flutter 第五课 --- 包管理器和资源管理
- Flutter 第六课 --- flutter网络请求
- Flutter 第七课 --- flutter 网络封装
- Flutter 第八课 ---使用 Flutter 构建 Web 应用
- 如何正确的在flutter中添加webview
前言
今天讲的这个话题就很有趣,是关于flutter与js的交互,这也是基本刚需,为我们把原生项目编译H5打好基础,只有这样,我们所使用的热更新才会更加完美。我们今天用到的插件是webview_flutter。
webview_flutter
简单介绍一下插件api
- onWebViewCreated:在WebView创建完成后调用,只会被调用一次;
- initialUrl:初始load的url;
- javascriptMode:JS执行模式(是否允许JS执行);
- javascriptChannels:JS和Flutter通信的Channel;
- navigationDelegate:路由委托(可以通过在此处拦截url实现JS调用Flutter部分);
- onPageFinished:WebView加载完毕时的回调。
JS调用Flutter
JS调用Flutter有两种方法:使用javascriptChannels发送消息和使用路由委托(navigationDelegate)拦截url。今天的主角是使用javascriptChannels发送消息,关于路由委托的学习后再未来的文章中讲述
flutter中加载webview
关于这个话题我在上一篇文章中已经做过详细解释。javascriptChannels参数可以传入一个对象,对象中有一个属性onMessageReceived,它的值是一个函数,函数的形参就是js传递给flutter的参数(包括回调函数名)
import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebviewApp extends StatefulWidget {
const WebviewApp({Key? key}) : super(key: key);
@override
State<WebviewApp> createState() => _WebviewAppState();
}
class _WebviewAppState extends State<WebviewApp> {
late WebViewController controller;
@override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = AndroidWebView();
}
@override
Widget build(BuildContext context) {
return WebView(
initialUrl: 'https://jolly-twilight-a037fd.netlify.app/', // 这是是js文件线上地址
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) async {
controller = webViewController;
},
javascriptChannels: <JavascriptChannel>{
JavascriptChannel(
name: "handleMessage",
onMessageReceived: (JavascriptMessage message) async {
print("flutter 调用了js,参数是${message.message}"); // {"function":"getFlutterData","params":{"operation":"分享"}} getFlutterData 就是回调函数
var functionName = jsonDecode(message.message)["function"];
return controller.runJavascript("$functionName('123465789')"); // flutter 返回参数给js (js端显示打印结果是:"flutter 返回参数是 123465789")
})
},
);
}
}
附上js线上代码(防止误删你们看不到)
最重要的就是需要再js 端实现回调函数,不然flutter跟js的交互,就无法相互传递参数了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div style="margin-top: 20px">
<h2 id="aaaa">JS与Flutter交互</h2>
<input type="button" value="唤起本地方法" onclick=inputClick()>
</div>
</body>
<script>
function inputClick () {
handleMessage.postMessage(JSON.stringify({
function: "getFlutterData",
params: {operation: '分享' }
}))
}
function getFlutterData(data){
console.log("flutter 返回参数是", data);
}
</script>
</html>
在上面的例子中,evaluateJavascript()返回值是一个Future,因此我们可以接收JS给我们的返回值,返回值格式请阅读官方API注释。 这里要注意的是,evaluateJavascript()方法,Flutter建议我们在onPageFinished回调之后去执行,以保证所有的HTML都已经加载完毕了。
结束语
关于flutter调用js的简使用,到这就结束了,如果你有什么疑问,可以在评论区留下问题或者私信我,如果你是很出色flutter的大佬,还希望得到你的指导和肯定。