美文网首页
Flutter应用开发之webview_flutter插件

Flutter应用开发之webview_flutter插件

作者: xieyinghao | 来源:发表于2023-06-06 07:24 被阅读0次

    和其他Flutter插件的使用方式一样,使用webview_flutter之前需要先在pubspec.yaml文件中添加依赖脚本,如下所示。

    dependencies:
       webview_flutter: ^0.3.22+1
    

    然后,我们使用flutter packages get命令将webview_flutter插件拉取到本地后,就可以使用它进行网页加载开发了。

    基本使用

    如下所示,是WebView组件的构造函数。

    WebView({
        Key key,
        this.onWebViewCreated,             //WebView创建完成之后的回调
        this.initialUrl,                               // 初始化 URL
        this.javascriptMode = JavascriptMode.disabled,    //JS执行模式,默认是不调用
        this.javascriptChannels,             // JS可以调用Flutter 的通道
        this.navigationDelegate,            // 路由委托,可以使用它执行拦截操作
        this.gestureRecognizers,          // 手势相关
        this.onPageStarted,                 //开始加载页面回调
        this.onPageFinished,              // 页面加载完成的回调
        this.onWebResourceError,     //资源加载失败回调
        this.debuggingEnabled = false,
        this.gestureNavigationEnabled = false,
        this.userAgent,
        this.initialMediaPlaybackPolicy =
            AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
      })
    

    使用时,只需要按照参数传递对应的值即可。不过,在实际使用前,为了方便使用,我们一般会对它进行二次封装,主要是界面和功能的封装。下面是我封装的一个可以加载本地和网络文件的WebViewPage。

    class WebViewPage extends StatefulWidget {
    
      String url;
      final String title;
      final bool isLocalUrl;
    
      WebViewController _webViewController;
    
      WebViewPage({this.url, this.isLocalUrl = false, this.title});
    
      @override
      _WebViewPage createState() => _WebViewPage();
    
    
    }
    
    class _WebViewPage extends State<WebViewPage> {
    
      JavascriptChannel jsBridge(BuildContext context) => JavascriptChannel(
          name: 'jsbridge', // 与h5 端的一致 不然收不到消息
          onMessageReceived: (JavascriptMessage message) async{
            debugPrint(message.message);
          });
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: _buildAppbar(),
            body: _buildBody()
        );
      }
    
      _buildAppbar() {
        return AppBar(
            elevation: 0,
            backgroundColor: Color(0xccd0d7),
            title: Text(widget.title, style: TextStyle(color: Colors.black),),
            centerTitle: true,
            leading: IconButton(icon: Icon(Icons.arrow_back, color: Color(0xFF23ADE5),), onPressed: () {
    
            })
        );
      }
    
      _buildBody() {
        return Column(
          children: <Widget>[
            SizedBox(
              height: 1,
              width: double.infinity,
              child: const DecoratedBox(decoration: BoxDecoration(color: Color(0xFFEEEEEE))),
            ),
            Expanded(
              flex: 1,
              child: WebView(
                initialUrl: widget.isLocalUrl ? Uri.dataFromString(widget.url, mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
                    .toString(): widget.url,
                javascriptMode: JavascriptMode.unrestricted,
                javascriptChannels: <JavascriptChannel>[
                  jsBridge(context)
                ].toSet(),
                onWebViewCreated: (WebViewController controller){
                  widget._webViewController = controller;
                  if(widget.isLocalUrl){
                      _loadHtmlAssets(controller);
                  }else{
                    controller.loadUrl(widget.url);
                  }
                  controller.canGoBack().then((value) => debugPrint(value.toString()));
                  controller.canGoForward().then((value) => debugPrint(value.toString()));
                  controller.currentUrl().then((value) => debugPrint(value));
                },
                onPageFinished: (String value){
                  widget._webViewController.evaluateJavascript('document.title')
                      .then((title) => debugPrint(title));
                },
              ),
            )
          ],
        );
      }
    
    //加载本地文件
      _loadHtmlAssets(WebViewController controller) async {
        String htmlPath = await rootBundle.loadString(widget.url);
        controller.loadUrl(Uri.dataFromString(htmlPath,mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
            .toString());
      }
    
    }
    

    使用时,只需要按照传入对应的属性即可。需要说明的是,加载本地Html文件时,需要在pubspec.yaml文件中申明这个Html文件,如下所示。

    flutter:
     //  ...
      assets:
       - assets/real_data_help.html
    

    然后,我们使用封装的组件即可加载本地的Html文件。例如:

    class MyApp extends StatelessWidget {
    
      String localUrl = 'assets/real_data_help.html';
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home:WebViewPage(url:localUrl, isLocalUrl: true, title: '加载本地文件'),
        );
      }
    }
    

    来源:https://zhuanlan.zhihu.com/p/158682432

    相关文章

      网友评论

          本文标题:Flutter应用开发之webview_flutter插件

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