启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情
Flutter系列文章列表
- 2022年了,你还不会flutter!!!
- Flutter 第一课---flutter特点及组件开发
- Flutter 第二课---组件生命周期和App生命周期
- Flutter 第三课---状态管理之Provide
- Flutter 第四课---路由管理
- Flutter 第五课 --- 包管理器和资源管理
- Flutter 第六课 --- flutter网络请求
- Flutter 第七课 --- flutter 网络封装
- Flutter 第八课 ---使用 Flutter 构建 Web 应用
- 如何正确的在flutter中添加webview
- flutter原生 与 js 交互
前言
在上一节中我们讲到了flutter原生与js之间的交互,答案也很简单,是通过第三方库webview来实现。那么今天我们来讲如何把flutter web(就是flutter 编译成web 项目,运行在浏览器端)与 js 是如何实现通信的。
说明:Flutter 调用JS 需要 import dart.js 作为支持,如果项目中一旦导入 dart.js 项目则无法运行打包App 了,就只能运行在浏览器中。
Flutter 调用 Js
flutter_web 端代码如下
import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:js' as js;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Bridge',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Bridge Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ElevatedButton(
child: const Text("调用js代码"),
onPressed: () {
// 这里就是 flutter web 如何调用js 方法
var personInfo = js.context.callMethod('js2PersonInfo');
print("personInfo is $personInfo");
debugPrint("Flutter调用JS端方法js2PersonInfo结果为:${jsonDecode(personInfo)}");
},
)
);
}
}
我们把这个项目通过flutter web build编译成web,可以在项目根目录下找到/build/web,然后部署在本地服务器中,有很多方案,这里比较简单的方法就是在web 文件下运行Node命令(npx serve),启动一个本地服务器。然后在webview中注入
fluuter_bridge 代码如下:
import 'package:flutter/material.dart';
import 'dart:io';
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> {
@override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = AndroidWebView();
}
@override
Widget build(BuildContext context) {
return const WebView(
// 注入flutter web 代码
initialUrl: 'http://192.168.0.44:3000/#/',
javascriptMode: JavascriptMode.unrestricted,
);
}
}
js端调用方法
这个文件可以在根目录web/html中书写
function js2PersonInfo(){
const Person = {
name: 'John',
sex: 'women',
age: 36,
}
console.log(JSON.stringify(Person))
const jsonString = JSON.stringify(Person)
return jsonString;
}
Js 调用 Flutter
先通过flutter在window中注入一个方法,然后在js中调用这个方法。
import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:js' as js;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Bridge',
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int add(int a, int b){
return a + b;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ElevatedButton(
child: const Text("normal"),
onPressed: () {
js.context["add"]=add;
var result = js.context.callMethod('test');
debugPrint("Flutter调用JS端方法test结果为:$result");
},
)
);
}
}
js 端代码:
function test() {
var sum = window.add(12,23);
console.log("sum 的值为:",sum);
return sum;
}
这样我们就完美实现了flutter web 与 js之间的通信,通过上一节文章,我们就完成了flutter、flutter web和 js 之间的通信了。在初次尝试通信时,我也很受打击,我很开心,自己最终坚持了下来,下节课我们来说所在fluuter 中如何调用一个js Promise,这个坑巨大,希望有兴趣的可以参与进来,一起探讨。