flutter:webview

06-02 1254阅读

前言

最近在研究如何在应用程序中嵌入Web视图,发现有两个库不错。

flutter:webview

一个是官方维护、一个是第三方维护。因为没说特别的需求,就使用了官方库,实现一些简单功能是完全ok的

webview_flutter

不建议使用,因为效果不怎么样,当然也可能是我太菜不会用,下面这个问题就很难理解为什么会这样?

flutter:webview

基本使用

官方文档

https://pub-web.flutter-io.cn/packages/webview_flutter

安装

flutter pub add webview_flutter

加载并显示web

可以加载html字符串,也可以直接加载url链接。官方都提供了对应的方法,这里演示加载url

  • 初始化
     late WebViewController webViewController;
      //初始化
      @override
      void initState() {
        super.initState();
        webViewController = WebViewController()
          ..setJavaScriptMode(JavaScriptMode.unrestricted);
      }
    
    • 显示

      显示的时候一般需要结合FutureBuilder,比较这是一个异步的过程

      FutureBuilder(
           // 异步方法
           future: searchNovelFromWeb(),
           builder: (context, snapshot) {
             // 等待状态显示的widget
             if (snapshot.connectionState == ConnectionState.waiting) {
               return const Center(
                 child: CircularProgressIndicator(),
               );
               //  错误时显示的widget
             } else if (snapshot.hasError) {
               return const Text('Error');
             } else {
               return snapshot.data ?? const Text('No data');
             }
           }))
        Future searchNovelFromWeb() async {
          Widget res;
          try {
            await webViewController
                .loadRequest(Uri.parse('https://m.bbxxxxxx.com/s?q=凡人修仙'));
            res = WebViewWidget(controller: webViewController);
          } catch (error) {
            res = Text("加载失败:${error.toString()}");
            print("加载失败:${error.toString()}");
          }
          return res;
        }
      

      flutter:webview

      flutter:webview

      flutter与web之间的交互

      flutter通知web,让web执行某些操作

      官方提供了两个方法:runJavaScript、runJavaScriptReturningResult。后者可以向flutter返回执行结果

      比如在网页加载完成后获取到网页源代码

      webViewController.setNavigationDelegate(
            NavigationDelegate(onPageFinished: (url) async {
          print("页面加载完成:$url");
             
           var html = await webViewController.runJavaScriptReturningResult(
             "document.documentElement.innerText;");
            debugPrint("结果是11:$html", wrapWidth: 1024);
        }));
      

      flutter:webview

      web发生变化后,通知flutter

      这块也实现了,但是不太稳定,有时候不能够正常运行

       await webViewController
                .loadRequest(Uri.parse('https://m.bbxxxxxxxt.com/s?q=凡人修仙'));
            webViewController.setNavigationDelegate(
                NavigationDelegate(onPageFinished: (url) async {
              print("页面加载完成:$url");
              // 添加监听
               await webViewController.addJavaScriptChannel('Report',
                   onMessageReceived: (JavaScriptMessage message) {
                 print("收到了消息,是:${message.message}");
               });
               // 注入脚本
               await  webViewController.runJavaScript('''
                  setInterval(() => {
                    let time = new Date().toLocaleTimeString();
                     Report.postMessage(time);
                 },1000)
               ''');
            }));
      

      flutter:webview

      flutter_inappwebview

      功能更多,这里只会简单介绍一下,具体使用可以查看官方文档、官方案例。

      强烈推荐:功能更多,而且原来使用webview_flutter无法实现的功能,现在轻而易举的实现了。

      官方文档

      官方案例

      安装

      flutter pub add flutter_inappwebview
      

      基本使用

      这里遇到个问题,版本过高导致构建失败了。我现在用的版本是:5.6.0

      // 将html字符串解析为dom的库
      import 'package:html/parser.dart';
      import 'package:flutter_inappwebview/flutter_inappwebview.dart';
      late InAppWebViewController inAppWebViewController;
      
      res = InAppWebView(
         initialUrlRequest:
             URLRequest(url: Uri.parse('https://onion.inscode.cc/')),
         onLoadStop: (controller, url) async {
           // 加载完成
           inAppWebViewController = controller;
           print("加载地址:$url");
           var html = await controller.getHtml();
           debugPrint("html是:${html.toString().trim()}");
           var dom = parse(html);
           print("标题是:${dom.querySelector('.title')?.text}");
         },
       );
      

      flutter:webview

      执行脚本

      要等页面加载完成后才能执行

       // 执行脚本
       var body = await inAppWebViewController.evaluateJavascript(
           source: "document.body.innerHTML");
       debugPrint("执行结果:${body.toString().trim()}");
      

      flutter:webview

      遇到的问题

      最开始我的想法是执行函数,然后更新要显示的组件,但是resBody 一直没有更新。后来发现好像是onLoadStop没有执行,仔细思考后应该是InAppWebView初始化后,没有在页面上显示导致后续方法没有执行。解决方法就是让InAppWebView在页面上显示,当然可能不想在页面显示,这时给它父容器设置一个高度比如1,这样就可以解决这个问题。

        Future searchNovelFromWeb() async {
          String html = '';
          InAppWebView(
            initialUrlRequest:
                URLRequest(url: Uri.parse('https://onion.inscode.cc/')),
            onLoadStop: (controller, url) async {
              inAppWebViewController = controller;
              print("开始搜索了");
              html = await inAppWebViewController.getHtml() ?? '1111';
              debugPrint("查询的值:${html.toString()}");
              setState(() {
                resBody = const Text("搜索完成");
              });
            },
          );
        }
      
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码