You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter WebView中WillPopScope异常,求修改onWillPop方法方案

修复WebView返回按钮逻辑问题

问题现状

当前点击返回按钮时,直接触发WillPopScope的退出确认对话框,未先尝试返回WebView的上一页,不符合网页浏览的常规逻辑。

修改方案

  1. 将WebViewController和Completer改为类成员变量(避免在build方法内声明导致每次重建丢失引用)
  2. 在onWillPop中优先检查WebView是否存在历史记录:
    • 若可返回上一页,调用goBack()并返回false阻止默认退出行为
    • 若已处于首页,再弹出退出确认对话框

修改后的完整代码示例

调整类成员变量

class YourWebViewPage extends StatefulWidget {
  final String homeURL;
  const YourWebViewPage({Key? key, required this.homeURL}) : super(key: key);

  @override
  State<YourWebViewPage> createState() => _YourWebViewPageState();
}

class _YourWebViewPageState extends State<YourWebViewPage> {
  late WebViewController _controller;
  final Completer<WebViewController> _controllerCompleter = Completer<WebViewController>();
  
  // 其他成员方法...
}

修改onWillPop方法

onWillPop: () async {
  // 先检查WebView是否能返回上一页
  if (await _controller.canGoBack()) {
    _controller.goBack();
    return false; // 阻止默认退出行为
  } else {
    // 无法返回时弹出确认对话框
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text("Xác nhận thoát"),
          content: const Text("Bạn có chắc bạn muốn thoát?"),
          actions: <Widget>[
            TextButton(
              child: const Text("VÂNG"),
              onPressed: () {
                SystemNavigator.pop();
              },
            ),
            TextButton(
              child: const Text("KHÔNG"),
              onPressed: () {
                Navigator.of(context).pop();
              },
            )
          ],
        );
      }
    );
    return false; // 由对话框操作处理退出逻辑
  }
},

调整build方法中的WebView初始化

@override
Widget build(BuildContext context) {
  return WillPopScope(
    onWillPop: // 上述修改后的onWillPop方法
    child: netState
        ? Scaffold(
            body: Padding(
              padding: const EdgeInsets.only(top: 32),
              child: WebView(
                initialUrl: widget.homeURL,
                zoomEnabled: false,
                userAgent: 'random',
                javascriptMode: JavascriptMode.unrestricted,
                onWebViewCreated: (WebViewController webViewController) {
                  _controllerCompleter.complete(webViewController);
                  _controller = webViewController;
                },
                navigationDelegate: (NavigationRequest request) {
                  if (request.url.startsWith(widget.homeURL) ||
                      request.url.contains("https://test-payment.momo.vn/") ||
                      request.url.contains("https://payment.momo.vn/") ||
                      request.url.startsWith("momo://app?action=payWithAppToken&amount=") ||
                      request.url.contains("google.com") ||
                      request.url.contains("facebook.com")) {
                    return NavigationDecision.navigate;
                  } else {
                    _launchURL(request.url);
                    return NavigationDecision.prevent;
                  }
                },
              ),
            ),
          )
        : // 无网络状态下的UI组件
  );
}

关键说明

  • 类成员级别的WebViewController是核心,确保能持续获取WebView的历史状态
  • canGoBack()方法用于检测WebView是否存在可返回的历史页面
  • 返回false是为了拦截WillPopScope的默认退出流程,优先执行WebView的返回逻辑

内容的提问来源于stack exchange,提问作者Ram Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 02:20:28