статус-кво
В настоящее время существует два основных подключаемых модуля,flutter_webview_plugin
а такжеwebview_flutter
.flutter_webview_plugin
Это сторонний плагин, и документация будет более полной.star
Тоже самое. Но есть две основные проблемы при использовании:
- Не могу вызвать метод Flutter в JS
- Невозможно перехватить H5 перед вводом URL
Так что в этой статье используется официальнаяwebview_flutter, в настоящее время все еще находится в предварительной версии, с нетерпением жду новых функций
Установить плагин
pubspec.yaml
dependencies
Увеличиватьwebview_flutter: ^0.3.13
, используйте последнюю версию,
dependencies:
webview_flutter: ^0.3.13
info.list
дорожка: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>
использовать
Список параметров
имя параметра | Типы | По умолчанию | иллюстрировать |
---|---|---|---|
initialUrl | String | '' | |
onWebViewCreated | Function | Вызывается при создании WebView | |
javascriptMode | JavascriptMode | JavascriptMode.disabled | Режим выполнения JS не вызывается по умолчанию |
javascriptChannels | Set | Используйте JavaScriptChannel JS для вызова Flutter | |
navigationDelegate | Function | запрос на перехват | |
onPageFinished | Function | вызов завершения загрузки страницы | |
gestureRecognizers | Set | жест |
Сцены
Самый простой способ загрузить URL
WebView(
initialUrl: "https://flutterchina.club/",
//JS执行模式 是否允许JS执行
javascriptMode: JavascriptMode.unrestricted
)
h5 вызывает флаттер -- JavascriptChannel
// 往h5 window 里面插入全局方法 Toaster
JavascriptChannel _toastJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
print(message);
Fluttertoast.showToast(
msg: message.message
);
});
}
// 往 Webview 组件注册 javascriptChannels
new WebView(
...
javascriptChannels: <JavascriptChannel>[ //javascriptChannels这个是api提供的互调的方法,
_toastJavascriptChannel(context),
].toSet()
)
// js 调用
Toaster.postMessage('js call flutter success!!')
h5 вызывает флаттер -- 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
);
}));
return NavigationDecision.prevent;
}
)
флаттер колл h5
// 在页面加载完毕,修改 Webview 的标题
new WebView(
...
onPageFinished: (url) {
// 设置标题
_controller.evaluateJavascript("document.title").then((result){
print(result);
setState(() {
widget.title = result;
});
});
},
)
полные компоненты
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;
},
/**
* 当 url 带有 'm=webview',则打开新的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
);
}));
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
onPageFinished: (url) {
// 设置标题
_controller.evaluateJavascript("document.title").then((result){
print(result);
setState(() {
widget.title = result;
});
});
// var a = '123';
// print(a+1);
// 测试flutter 调用我页面的方法
// _controller.evaluateJavascript("callJSFunc();").then((result){
// // print('callJSFunc has called: $result');
// });
},
javascriptChannels: <JavascriptChannel>[ //javascriptChannels这个是api提供的互调的方法,
_toastJavascriptChannel(context),
].toSet()
)
],
),
);
}
}
todo
- доступ к кордове
- Получить сетевой статус устройства