The status quo
There are two main plug-ins, Flutter_webview_plugin and webview_flutter. Flutter_webview_plugin is a third-party plugin that is fully documented and has the largest number of stars. But there are two major problems:
- The Flutter method cannot be called in JS
- You cannot intercept H5 before it enters a URL
So this article uses the official Webview_FLUTTER, which is currently in preview release and expects more features
Installing a plug-in
pubspec.yaml
Add webview_flutter to dependencies: ^0.3.13
Dependencies: webview_flutter: ^ 0.3.13Copy the code
info.list
Path: ios/Runner/info.list
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
Copy the code
use
Parameters in
Parameter names | type | The default value | instructions |
---|---|---|---|
initialUrl | String | ‘ ‘ | |
onWebViewCreated | Function | Called when the WebView is created | |
javascriptMode | JavascriptMode | JavascriptMode.disabled | JS execution mode does not call by default |
javascriptChannels | Set | Flutter can be invoked using javascriptChannel JS | |
navigationDelegate | Function | Intercept request | |
onPageFinished | Function | Page load complete call | |
gestureRecognizers | Set | gestures |
scenario
Load a URL as easily as possible
WebView(
initialUrl: "https://flutterchina.club/".// Whether JS execution mode allows JS execution
javascriptMode: JavascriptMode.unrestricted
)
Copy the code
H5 calls flutter — JavascriptChannel
// Insert the global Toaster method into the h5 window
JavascriptChannel _toastJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
print(message);
Fluttertoast.showToast(
msg: message.message
);
});
}
// register javascriptChannels with the Webview component
new WebView(
...
javascriptChannels: <JavascriptChannel>[ //javascriptChannels is the intermodulation method provided by the API,
_toastJavascriptChannel(context),
].toSet()
)
/ / js calls
Toaster.postMessage('js call flutter success!! ')
Copy the code
H5 calls flutter — navigationDelegate
new WebView(
...
navigationDelegate: (NavigationRequest request) {
// print('navigationDelegate: ${request.url}');
if(request.url.indexOf('m=webview') > - 1) {
String _url = helper.addUrlParam(request.url.replaceAll('&m=webview'.' '));
Navigator.of(context).push(new MaterialPageRoute(builder: (_) {
return Browser(
title: ' '.url: _url
);
}));
returnNavigationDecision.prevent; })Copy the code
Flutter call h5
// After the page is loaded, modify the Webview title
new WebView(
...
onPageFinished: (url) {
// Set the title
_controller.evaluateJavascript("document.title").then((result){
print(result); setState(() { widget.title = result; }); }); },)Copy the code
A complete component
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '.. /helper/index.dart' as helper;
class Browser extends StatefulWidget {
String url;
String title;
Browser({this.url, this.title});
@override
_BrowserState createState() => _BrowserState();
}
class _BrowserState extends State<Browser> {
dynamic _controller;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
JavascriptChannel _toastJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
print(message);
Fluttertoast.showToast(
msg: message.message
);
});
}
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Stack(
children: <Widget>[
new WebView(
initialUrl: widget.url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) {
_controller = controller;
},
/ * ** When the URL has 'm= webView ', a new webView is opened
* /
navigationDelegate: (NavigationRequest request) {
// print('navigationDelegate: ${request.url}');
if(request.url.indexOf('m=webview') > - 1) {
String _url = helper.addUrlParam(request.url.replaceAll('&m=webview'.' '));
Navigator.of(context).push(new MaterialPageRoute(builder: (_) {
return Browser(
title: ' ',
url: _url
);
}));
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
onPageFinished: (url) {
// Set the title
_controller.evaluateJavascript("document.title").then((result){
print(result);
setState(() {
widget.title = result;
});
});
// var a = '123';
// print(a+1);
// Test the method that flutter calls my page
// _controller.evaluateJavascript("callJSFunc();" ).then((result){
// // print('callJSFunc has called: $result');
// });
},
javascriptChannels: <JavascriptChannel>[ //javascriptChannels is the intermodulation method provided by the API,_toastJavascriptChannel(context), ].toSet() ) ], ), ); }}Copy the code
todo
- Access cordova
- Obtain the network status of the device
Refer to the article
- Flutter Hybrid Development (Interactive Communication)
- Easy guide to Flutter WebView and JS interaction
- Use WebView in Flutter