前言
需求,app中使用webview和h5交互,根据h5发过来的消息,在屏幕上展示flutter组件,并且可以发送消息给h5。
首先使用的组件是flutter_WebView_plugin,这个组件不能嵌套flutter组件,所以放弃这个组件。
flutter_inappbrowser 可以实现组合布局, 所以选用了此库, GitHub链接
[https://github.com/pichillilorenzo/flutter_inappbrowser
HTML发消息给app
//html 代码
window.flutter_inappbrowser.callHandler('test','hello',1234).then(function(result) {
console.log(result, typeof result);
console.log(JSON.stringify(result), result);
});
//app端代码
webView.addJavaScriptHandler('test', (args) {
print("收到来自web的消息"+args.toString());
});
app发送消息给HTML,通过注入js的方式,h5端定义方法 APP端调用
//h5端
window.appSendJs = function(args){
console.log(args)
document.getElementById('text').innerHTML = args
}
//app端
webView.injectScriptCode("window.appSendJs('hello')");
完整代码
h5端
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Flutter InAppBrowser demo</title>
<link rel="stylesheet" href="https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/demo.css">
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body >
<div class="main">
<div class="content">
<!-- <input /> -->
<button style="background-color: aqua;" onclick="dianji()">给APP发消息</button>
</div>
<button style="background-color: aqua;margin-top: 20px">更改body背景颜色</button>
<span style="margin-top:20px">接收到APP的消息:
<span id="text"></span>
</span>
</div>
<script>
window.addEventListener("flutterInAppBrowserPlatformReady", function(event) {
console.log("ready");
window.flutter_inappbrowser.callHandler('handlerFoo').then(function(result) {
console.log(result, typeof result);
console.log(JSON.stringify(result), result.bar);
});
window.flutter_inappbrowser.callHandler('handlerFooWithArgs', 1, true, ['bar', 5], {foo: 'baz'}).then(function(result) {
console.log(result, typeof result);
console.log(JSON.stringify(result));
});
});
function dianji(){
window.flutter_inappbrowser.callHandler('test','hello',1234).then(function(result) {
console.log(result, typeof result);
console.log(JSON.stringify(result), result);
});
}
window.appSendJs = function(args){
console.log(args)
document.getElementById('text').innerHTML = args
}
</script>
</body>
</html>
flutter完整代码
import 'package:flutter/material.dart';
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';
class DemoScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return new DemoScreenState();
}
}
class DemoScreenState extends State<DemoScreen> {
InAppWebViewController webView;
String url = "";
double progress = 0;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('h5交互',style:TextStyle(fontSize: 17)),
centerTitle: true,
),
body: Column(children: <Widget>[
Container(
padding: EdgeInsets.all(20.0),
child: Text(
"CURRENT URL\n${(url.length > 50) ? url.substring(0, 50) + "..." : url}"),
),
Container(
padding: EdgeInsets.all(10.0),
child: progress < 1.0 ? LinearProgressIndicator(value: progress) : null
),
Expanded(
child: InAppWebView(
initialFile: "assets/demo.html",
initialHeaders: {},
initialOptions: {
//"useShouldOverrideUrlLoading": true,
//"useOnLoadResource": true
},
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
webView.addJavaScriptHandler('test', (args) {
print("收到来自web的消息"+args.toString());
});
webView.addJavaScriptHandler('handlerFooWithArgs', (args) {
print(args);
return [args[0] + 5, !args[1], args[2][0], args[3]['foo']];
});
},
onLoadStart: (InAppWebViewController controller, String url) {
print("started $url");
setState(() {
this.url = url;
});
},
onLoadStop: (InAppWebViewController controller, String url) async {
print("stopped $url");
},
onProgressChanged:
(InAppWebViewController controller, int progress) {
setState(() {
this.progress = progress / 100;
});
},
shouldOverrideUrlLoading: (InAppWebViewController controller, String url) {
print("override $url");
controller.loadUrl(url);
},
onLoadResource: (InAppWebViewController controller, WebResourceResponse response, WebResourceRequest request) {
print("Started at: " +
response.startTime.toString() +
"ms ---> duration: " +
response.duration.toString() +
"ms " +
response.url);
},
onConsoleMessage: (InAppWebViewController controller, ConsoleMessage consoleMessage) {
print("""
console output:
sourceURL: ${consoleMessage.sourceURL}
lineNumber: ${consoleMessage.lineNumber}
message: ${consoleMessage.message}
messageLevel: ${consoleMessage.messageLevel}
""");
},
),
),
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text('修改h5样式'),
onPressed: () {
if (webView != null) {
webView.injectScriptCode('''
document.body.style.backgroundColor = 'green';
''');
}
},
),
RaisedButton(
child: Text('发送消息给h5'),
onPressed: () {
if (webView != null) {
webView.injectScriptCode("window.appSendJs('hello')");
}
},
),
RaisedButton(
child: Icon(Icons.refresh),
onPressed: () {
if (webView != null) {
webView.reload();
}
},
),
],
),
]),
);
}
}
网友评论