|
@@ -45,14 +45,80 @@ class _WebViewPageState extends State<WebViewPage> {
|
|
|
_showAppbar = widget.showAppbar ?? true;
|
|
|
Log.d("传入的initialUrl:${widget.initialUrl}");
|
|
|
_initialUrl = widget.initialUrl ?? widget.arguments!['initialUrl'];
|
|
|
- if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
|
|
|
+
|
|
|
+ _initializeController();
|
|
|
+ }
|
|
|
+
|
|
|
+ void _initializeController() {
|
|
|
+ webViewController = WebViewController()
|
|
|
+ ..setJavaScriptMode(JavaScriptMode.unrestricted)
|
|
|
+ ..setBackgroundColor(const Color(0x00000000))
|
|
|
+ ..setNavigationDelegate(
|
|
|
+ NavigationDelegate(
|
|
|
+ onProgress: (int progress) {
|
|
|
+ if (progress == 100) {
|
|
|
+ Future.delayed(const Duration(milliseconds: 500)).then((value) => {
|
|
|
+ // 获取页面高度
|
|
|
+ _getWebViewHeight()
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onPageStarted: (String url) {
|
|
|
+ if (mounted) {
|
|
|
+ setState(() {
|
|
|
+ _stackToView = 1;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onPageFinished: (String url) {
|
|
|
+ if (mounted) {
|
|
|
+ setState(() {
|
|
|
+ _stackToView = 0;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onWebResourceError: (WebResourceError error) {},
|
|
|
+ onNavigationRequest: (NavigationRequest request) async {
|
|
|
+ if (request.url.startsWith('tel:')) {
|
|
|
+ // 拦截tel链接
|
|
|
+ if (!await launchUrl(Uri.parse(request.url))) throw 'Unable to activate the call function';
|
|
|
+ return NavigationDecision.prevent; // 阻止WebView导航到该链接
|
|
|
+ }
|
|
|
+ return NavigationDecision.navigate;
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ ..loadRequest(Uri.parse(_initialUrl ?? ""));
|
|
|
+ }
|
|
|
+
|
|
|
+ _getWebViewHeight() async {
|
|
|
+ // try {
|
|
|
+ // final result = await webViewController?.runJavaScriptReturningResult('''
|
|
|
+ // new Promise((resolve) => {
|
|
|
+ // const scrollHeight = document.documentElement.scrollHeight;
|
|
|
+ // resolve(scrollHeight);
|
|
|
+ // });
|
|
|
+ // ''');
|
|
|
+ // return double.parse(result.toString());
|
|
|
+ // } catch (e) {
|
|
|
+ // return 300.0; // 默认高度
|
|
|
+ // }
|
|
|
+
|
|
|
+ // 方式二:
|
|
|
+ var originalHeight = await webViewController?.runJavaScriptReturningResult("document.body.offsetHeight;");
|
|
|
+ _webViewHeight = double.parse(originalHeight.toString());
|
|
|
+ if (mounted) {
|
|
|
+ setState(() {
|
|
|
+ _webViewHeight = _webViewHeight <= 0 ? 300 : _webViewHeight;
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
void dispose() async {
|
|
|
super.dispose();
|
|
|
// 销毁 WebView 实例
|
|
|
- webViewController?.loadUrl('about:blank');
|
|
|
+ webViewController?.loadHtmlString('about:blank');
|
|
|
webViewController?.clearCache();
|
|
|
}
|
|
|
|
|
@@ -64,80 +130,6 @@ class _WebViewPageState extends State<WebViewPage> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 注册js回调
|
|
|
- _invokeJavascriptChannel(BuildContext context) {
|
|
|
- return [
|
|
|
- JavascriptChannel(
|
|
|
- name: 'Invoke',
|
|
|
- onMessageReceived: (JavascriptMessage message) {
|
|
|
- // var webHeight = double.parse(message.message);
|
|
|
- // setState(() {
|
|
|
- // print('打印webHeight:$_webViewHeight');
|
|
|
- // _webViewHeight = webHeight;
|
|
|
- // });
|
|
|
- },
|
|
|
- ),
|
|
|
- JavascriptChannel(
|
|
|
- name: 'Invoke1',
|
|
|
- onMessageReceived: (JavascriptMessage message) {
|
|
|
- // var devicePixelRatio = double.parse(message.message);
|
|
|
- // setState(() {
|
|
|
- // _webViewHeight = devicePixelRatio;
|
|
|
- // });
|
|
|
- },
|
|
|
- ),
|
|
|
- JavascriptChannel(
|
|
|
- name: "integral",
|
|
|
- onMessageReceived: (JavascriptMessage message) {
|
|
|
- // print("交互");
|
|
|
- // print("参数: ${message.message}");
|
|
|
- // Map res = changeStringToJsonMap(message.message);
|
|
|
- // print(res["operation"]);
|
|
|
- // _controller?.evaluateJavascript("getAddressBook('sdad')");
|
|
|
- },
|
|
|
- ),
|
|
|
- JavascriptChannel(
|
|
|
- name: "MessageDeal",
|
|
|
- onMessageReceived: (JavascriptMessage message) async {
|
|
|
- // print("交互");
|
|
|
- // print("参数: ${message.message}");
|
|
|
- // print(webViewController);
|
|
|
- // webViewController
|
|
|
- // ?.runJavascriptReturningResult("showMessage('我(Flutter)收到了你的消息)");
|
|
|
- // _controller?.evaluateJavascript("document.title");
|
|
|
- },
|
|
|
- ),
|
|
|
- JavascriptChannel(
|
|
|
- name: "callWithDict",
|
|
|
- onMessageReceived: (JavascriptMessage message) {
|
|
|
- // print("交互");
|
|
|
- // print("参数: ${message.message}");
|
|
|
- },
|
|
|
- ),
|
|
|
- ];
|
|
|
- }
|
|
|
-
|
|
|
- // 获取页面高度
|
|
|
- _getWebViewHeight() async {
|
|
|
- // 方式一:
|
|
|
- // await webViewController?.runJavascriptReturningResult('''
|
|
|
- // try {
|
|
|
- // // Invoke.postMessage([document.body.clientHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight]);
|
|
|
- // let scrollHeight = document.documentElement.scrollHeight;
|
|
|
- // if (scrollHeight) {
|
|
|
- // Invoke.postMessage(scrollHeight);
|
|
|
- // }
|
|
|
- // } catch {}
|
|
|
- // ''');
|
|
|
- // 方式二:
|
|
|
- var originalHeight = await webViewController!.runJavascriptReturningResult("document.body.offsetHeight;");
|
|
|
- _webViewHeight = double.parse(originalHeight);
|
|
|
- setState(() {
|
|
|
- _webViewHeight = _webViewHeight <= 0 ? 300 : _webViewHeight;
|
|
|
- });
|
|
|
- // print('网页高度-----' + _webViewHeight.toString());
|
|
|
- }
|
|
|
-
|
|
|
// 返回与后退的处理
|
|
|
Future<bool> _onWillPop() async {
|
|
|
if (webViewController == null) {
|
|
@@ -180,70 +172,21 @@ class _WebViewPageState extends State<WebViewPage> {
|
|
|
IndexedStack(
|
|
|
index: _stackToView,
|
|
|
children: [
|
|
|
+ //WebView控件
|
|
|
Column(
|
|
|
children: [
|
|
|
Expanded(
|
|
|
child: WillPopScope(
|
|
|
onWillPop: _onWillPop,
|
|
|
- child: WebView(
|
|
|
+ child: WebViewWidget(
|
|
|
key: _key,
|
|
|
- initialUrl: _initialUrl!.startsWith("http")
|
|
|
- ? _initialUrl
|
|
|
- : Uri.dataFromString(
|
|
|
- _initialUrl!,
|
|
|
- mimeType: 'text/html',
|
|
|
- encoding: Encoding.getByName('utf-8'),
|
|
|
- ).toString(),
|
|
|
-
|
|
|
- userAgent: '',
|
|
|
- //JS执行模式 是否允许JS执行
|
|
|
- javascriptMode: JavascriptMode.unrestricted,
|
|
|
- //webview创建好
|
|
|
- onWebViewCreated: (WebViewController controller) {
|
|
|
- webViewController = controller;
|
|
|
- },
|
|
|
- onProgress: (int progress) {
|
|
|
- // print('progress=====>$progress');
|
|
|
- if (progress == 100) {
|
|
|
- Future.delayed(const Duration(milliseconds: 500)).then((value) => {
|
|
|
- // 获取页面高度
|
|
|
- _getWebViewHeight()
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- onPageStarted: (String url) {
|
|
|
- // print('onPageStarted=====>$url');
|
|
|
- },
|
|
|
- onPageFinished: (String url) {
|
|
|
- Log.d('onPageFinished=====>$url');
|
|
|
- if (mounted) {
|
|
|
- setState(() {
|
|
|
- _stackToView = 0;
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- onWebResourceError: (WebResourceError error) {
|
|
|
- // print('error=====>$error');
|
|
|
- },
|
|
|
- gestureNavigationEnabled: true,
|
|
|
- // 注册js 回调
|
|
|
- javascriptChannels: _invokeJavascriptChannel(context).toSet(),
|
|
|
- navigationDelegate: (NavigationRequest request) async {
|
|
|
- //如果是tel标签需要阻止并调用 launchUrl 的方法调用拨打电话
|
|
|
- if (request.url.startsWith('tel:')) {
|
|
|
- // 拦截tel链接
|
|
|
- if (!await launchUrl(Uri.parse(request.url))) throw '无法启动拨打电话功能';
|
|
|
- return NavigationDecision.prevent; // 阻止WebView导航到该链接
|
|
|
- }
|
|
|
-
|
|
|
- // 可以继续WebView的内部跳转
|
|
|
- return NavigationDecision.navigate;
|
|
|
- },
|
|
|
+ controller: webViewController!,
|
|
|
),
|
|
|
),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
+ //Loading加载控件
|
|
|
Container(
|
|
|
color: Colors.white,
|
|
|
child: const Center(
|