Flutter webView添加加载进度百分比

在这里插入图片描述

Webview添加监听

//记载监听用于在dialog上回调
  late Function(int progress)? loadingListener;
  
  WebView(
                  initialUrl: ServiceUrl.homeWeb,
                  //javascript是否启用默认是(JavascriptMode.disabled禁用)
                  javascriptMode: JavascriptMode.unrestricted,
                  //开始加载
                  onPageStarted: (url) {
                    _showLoadingDialog(context);
                  },
                  onProgress: (int progress) {
                    loadingListener?.call(progress);
                    print('记载=$progress');
                  },

                  //加载结束
                  onPageFinished: (url) {
                    if (loadingDialogContext != null) {
                      Navigator.pop(loadingDialogContext!);
                    }
                  },
                  //加载错误
                  onWebResourceError: (WebResourceError error) {
                    if (loadingDialogContext != null) {
                      Navigator.pop(loadingDialogContext!);
                    }
                  },
                  navigationDelegate: (NavigationRequest navigation) {
                    print('拦截web点击=${navigation.url}');
                    _urlNavigation(navigation.url);
                    return NavigationDecision.prevent;
                  },
                ),

显示dialog

  void _showLoadingDialog(BuildContext context) {
    var progress = 0;
    showDialog<bool>(
      context: context,
      barrierColor: Colors.transparent,
      builder: (BuildContext context) {
        loadingDialogContext = context;
        return UnconstrainedBox(
          child: Container(
            alignment: Alignment.center,
            padding: const EdgeInsets.all(20),
            decoration: const BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(14)),
              shape: BoxShape.rectangle,
              color: Colors.white,
              boxShadow: [
                BoxShadow(
                    color: Colors.black26,
                    offset: Offset(2.0, 2.0),
                    blurRadius: 14)
              ],
            ),
            /*重点是需要使用StatefulBuilder设置dialog的局部刷新,
            如果直接在webview调用setState((){})是不能刷新
         	因为dialog是通过路由跳转显示的意思就是他跟webview是两个页面
         	所以setState只能更改当前webView的状态,
         	这里更Android里的弹窗是不同的
            */
            child: StatefulBuilder(
                builder: (BuildContext context, StateSetter _setState) {
              loadingListener = (progressValue) {
                _setState(() {
                  progress = progressValue;
                });
              };
              return Stack(
                alignment: Alignment.center,
                children: [
                  CircularProgressIndicator(
                    value: progress / 100,
                  ),
                  Text('$progress%')
                ],
              );
            }),
          ),
        );
      },
    );
  }

补充一点webview里面的navigationDelegate拦截识别跳转到对应的也页面,如点击了商品,分类…

///
  /// url识别拦截
  void _urlNavigation(String url) {
    //商品id识别
    if (url.contains('product_id:')) {
      var data = url.substring(url.lastIndexOf(":") + 1);
      _navigationProduct(data);
      print('product_id=$data');
      return;
    }
    //识别分类id
    if (url.contains("category_id:")) {
      var data = url.substring(url.lastIndexOf(":") + 1);
      _navigationProductList(data);
      return;
    }
  }

  ///跳转到商品详情
  void _navigationProduct(String? productId) {
    if (productId != null) {
      var id = int.parse(productId);
      Navigator.push(context, MaterialPageRoute(builder: (context) {
        return ProductDetailsPage(productId: id);
      }));
    }
  }

  ///跳转到商品列表
  void _navigationProductList(String? categoryId) {
    if (categoryId != null) {
      Navigator.push(context, MaterialPageRoute(builder: (context) {
        return ProductListPage(
          categoryId: categoryId,
        );
      }));
    }
  }

这里做个学习记录如果觉得不合理或者有更好的实现方式可以留言,加以改进【抱拳】【抱拳】


版权声明:本文为qq_30005223原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。