
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
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 Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
const String html = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport"
content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<title>Title</title>
</head>
<body>
<button onclick="callFlutter1()">js调用Flutter(javascriptChannels)</button>
<button onclick="callFlutter2()">js调用Flutter(navigationDelegate)</button>
<p id="p1" style="visibility:hidden;">
Flutter 调用了 JS.
Flutter 调用了 JS.
Flutter 调用了 JS.
</p>
<img alt="http图片报错" class="has" src="https://img-blog.csdnimg.cn/20190703173020692.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW9taV8w,size_16,color_FFFFFF,t_70" width="300" height="600">
</body>
<script>
var testCallBack = '测试返回字符串';
function callFlutter1(){
channel.postMessage(JSON.stringify({name:"JS调用了Flutter"}));
}
function callFlutter2(){
document.location = "https://www.baidu.com/";
}
function callJS(message){
document.getElementById("p1").style.visibility = message;
}
</script>
</html>
''';
class _MyHomePageState extends State<MyHomePage> {
WebViewController controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0xff003050))
..loadHtmlString(html)
..addJavaScriptChannel('channel',
onMessageReceived: (JavaScriptMessage message) {
print('${message.message}----------${json.decode(message.message)}');
});
@override
initState() {
super.initState();
controller.setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
print('progress--------$progress');
},
onPageStarted: (String url) {
print('Started--------$url');
},
onPageFinished: (String url) {
print('Finished--------$url');
controller
.runJavaScriptReturningResult('callJS("visible")')
.then((value) => {print('+++++++$value')});
},
onWebResourceError: (WebResourceError error) {},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://www.baidu.com/')) {
print('blocking navigation to ------- ${request.url}');
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
);
}
@override
void didUpdateWidget(oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
}
@override
void dispose() {
super.dispose();
controller
..clearLocalStorage()
..clearCache()
..removeJavaScriptChannel('channel');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
backgroundColor: const Color(0xFF666666),
body: Column(
children: [
Container(
height: 400,
width: double.infinity,
color: Colors.greenAccent,
alignment: Alignment.topCenter,
child: WebViewWidget(controller: controller)),
],
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Text('Flutter调用JS'),
),
);
}
void _incrementCounter() {
controller.runJavaScriptReturningResult('testCallBack').then((value) => {
print('+++++++$value')
});
}
}