美文网首页
webview_flutter 远程或本地网页JaveScrip

webview_flutter 远程或本地网页JaveScrip

作者: antcore | 来源:发表于2019-11-22 13:35 被阅读0次

    完整实例代码 Gitee

    flutter dependencies

    dependencies:
      flutter:
        sdk: flutter
      webview_flutter: ^0.3.15+1
      fluttertoast: ^3.1.3
    
    class _ComponentWebviewState extends State<ComponentWebview> {
      bool _loading = false;
      WebViewController _webViewController;
      @override
      void initState() {
        super.initState();
      }
      @override
      Widget build(BuildContext context) {
        //加载  远程网页 OR 本地网页
        var isRemote = widget.url.contains('http');
        return Stack(
          children: <Widget>[
            Scaffold(
              body: isRemote ? loadRemoteUrl() : loadAssetsUrl(),
              floatingActionButton: FloatingActionButton(
                onPressed: () {
                  _webViewController
                      ?.evaluateJavascript(
                          'customeFunc("Flutter 调用 JS Time: ${DateTime.now().toUtc()}")')
                      ?.then((result) {
                    // You can handle JS result here.
                    print("customeFunc" + result);
                  });
                },
                child: Text('调用JS'),
              ),
            ),
            //加载网页提示
            uiLoading()
          ],
        );
      }
      Widget uiLoading() {
        if (_loading)
          return Center(child:CircularProgressIndicator()) ;//Center(child: Icon(Icons.play_circle_filled));
        else
          return Container(height: 0.0, width: 0.0);
      }
      // 定义 网页中能够调用的 Flutter 方法
      JavascriptChannel jsChannelShowToast(BuildContext context) {
        return JavascriptChannel(
            name: 'flutterShowToast',
            onMessageReceived: (JavascriptMessage message) {
              Fluttertoast.showToast(
                  msg: message.message,
                  toastLength: Toast.LENGTH_SHORT,
                  gravity: ToastGravity.CENTER,
                  timeInSecForIos: 1,
                  backgroundColor: Colors.red,
                  textColor: Colors.white,
                  fontSize: 16.0);
            });
      }
      ///JS和Flutter通信的Channel;
      /// js 调用 flutter 方法
      List<JavascriptChannel> _getWebViewJavascriptChannels() {
        return <JavascriptChannel>[
          jsChannelShowToast(context),
        ];
      }
      _navigationDelegateHandle(NavigationRequest request) {
        print('request.url =======> : ${request.url}');
        //路由委托(可以通过在此处拦截url实现JS调用Flutter部分);
        ///通过拦截url来实现js与flutter交互
        if (request.url.toLowerCase().startsWith('webviewflutterurl://')) {
          // Fluttertoast.showToast(msg:'JS调用了Flutter By navigationDelegate');
          print('blocking navigation to $request}');
          return NavigationDecision.prevent;
          ///阻止路由替换,不能跳转,因为这是js交互给我们发送的消息
        }
        return NavigationDecision.navigate;
        //允许路由替换
      }
      ///页面加载完成处理
      _onPageFinished(String url) async {
        // 获取当前加载页面的 title
        String title = await _webViewController.getTitle();
        widget.titleChandge(title);
        setState(() {
          _loading = false;
        });
        print('Page finished url ====> : $url');
        //添加一些 webview 初始化数据
        var jsonData = {'platform': Platform.isAndroid ? 'android' : 'ios'};
        var jsonDataString = jsonEncode(jsonData);
        print(jsonDataString);
        //通知网页服务器加载完成并触发加载完成事件
        _webViewController
            ?.evaluateJavascript(
                'triggerEventWebViewFlutterJSBridgeReady($jsonDataString)')
            ?.then((result) {
          print(result);
        });
      }
    }
    

    Remote 网页

      ///加载 远程 html
      Widget loadRemoteUrl() {
        return WebView(
            initialUrl: widget.url,
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (WebViewController webViewController) {
              setState(() { _loading = true; }); 
              _webViewController = webViewController;
            },
            javascriptChannels: _getWebViewJavascriptChannels().toSet(),
            navigationDelegate: (request) => _navigationDelegateHandle(request),
            onPageFinished: (url) => _onPageFinished(url));
      }
    

    localhost 网页

    需要引入

    import 'dart:io';
    import 'package:flutter/services.dart';
    
     
      ///加载 本地 html
      Widget loadAssetsUrl() {
        return FutureBuilder(
            future: _loadHtmlFile(),
            builder: (context, snapshot) => WebView(
                initialUrl: Uri.dataFromString(snapshot.data, mimeType: 'text/html',  encoding: Encoding.getByName('utf-8')) .toString(),
                javascriptMode: JavascriptMode.unrestricted,
                onWebViewCreated: (WebViewController webViewController) {
                  setState(() { _loading = true; });
                  _webViewController = webViewController;
                },
                javascriptChannels: _getWebViewJavascriptChannels().toSet(),
                navigationDelegate: (request) => _navigationDelegateHandle(request),
                onPageFinished: (url) => _onPageFinished(url)));
      }
      /// 加载本地 HTML 文件
      Future<String> _loadHtmlFile() async {
        return await rootBundle.loadString(widget.url);
      }
    

    网页部分

    <section style="text-align: center;">
            <div id="content"> </div>
            <button id="btnFlutterFunc">jquery调用Flutter</button> <hr>
            <button onclick="showToast()">原生Js调用Flutter</button> <hr>
            <a href="webviewflutterurl://fff?p1=123&p2=321">连接拦截 GO ==> :webviewflutterurl://fff?p1=123&p2=321</a>
        </section>
        <script type="text/javascript" src="./jquery.min.js"></script>
        <script type="text/javascript">
            function showToast(message) {
                flutterShowToast.postMessage(message || "JS调用了Flutter");
            }
            // 首先需要提前定义好事件,并且注册相关的EventListener
            var eventWebViewFlutterJSBridgeReady = new CustomEvent('webViewFlutterJSBridgeReady', {
                detail: { 
                    //平台 android OR ios
                    platform: '' 
                },
            });
            function triggerEventWebViewFlutterJSBridgeReady(jsonData) {
                console.log(JSON.stringify(jsonData))
                setTimeout(function () {
                    eventWebViewFlutterJSBridgeReady.detail.platform = jsonData.platform
                    if (window.dispatchEvent)
                        window.dispatchEvent(eventWebViewFlutterJSBridgeReady);
                    else
                        window.fireEvent(eventWebViewFlutterJSBridgeReady);
                }, 200)
                return '已触发事件:webViewFlutterJSBridgeReady:platform:${jsonData.platform}';
            }
            window.addEventListener('webViewFlutterJSBridgeReady', function (event) {
                console.log('触发:webViewFlutterJSBridgeReady');
            });
            window.addEventListener('webViewFlutterJSBridgeReady', function (event) {
                showToast('Js:CustomEvent:webViewFlutterJSBridgeReady'+JSON.stringify(event.detail));
            });
            function customeFunc(message) {
                document.getElementById("content").innerHTML = message;
                return 'customeFunc 调用完成'
            }
            $(function () {
                var elementContent = $('.content');
                var elementBtnFlutterFunc = $('#btnFlutterFunc');
                elementBtnFlutterFunc.unbind('click').bind('click', function () {
                    showToast();  
                })
            })
        </script>
    

    网页中加入 自定义事件 CustomEvent webViewFlutterJSBridgeReady
    以便通知网页网页加载完成 在调用的时候初始化部分 信息 如 硬件平台信息 等

    加载本地网页加载JQuery 还没研究透 ... 没找到方法

    String title = 'webview title';
      @override
      Widget build(BuildContext context) {
        var url = 'https://www.baidu.com';
        url = 'http://www.baidu.com';
        url = 'http://192.168.2.65:9777/Content/static/webview_flutter.html';
        var now =new DateTime.now();
        url = '$url?t=${now.toUtc()}';
        // url = "assets/www/webview_flutter.html";
        return Scaffold(
          appBar: AppBar(title:Text(title)),
          body: ComponentWebview(url: url,titleChandge: (value){
            print(value);
            setState(() {
              title = value;
            });
          }),
        );
      }
    

    关于WebView_Fultter 启用 http 请看 上一篇

    相关文章

      网友评论

          本文标题:webview_flutter 远程或本地网页JaveScrip

          本文链接:https://www.haomeiwen.com/subject/muofwctx.html