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

InAppWebView onLoadStop触发两次致AlertDialog重复弹出问题

解决InAppWebView检测搜索路由弹窗两次的问题

问题根源

点击维基百科移动端搜索图标后,页面哈希(#/search)的变化会多次触发onLoadStop回调,再加上原代码中isLoading的状态更新逻辑和哈希路由的加载特性不匹配,导致弹窗被重复调用两次。

修复方案

新增独立标志位控制弹窗仅触发一次,同时完善页面返回逻辑:

// 在State类中添加专属标志位
bool _hasShownSearchAlert = false;

InAppWebView(
  initialUrlRequest: URLRequest(url: Uri.parse(startPageUrl)),
  onLoadStart: (controller, url) {
    setState(() {
      isLoading = true;
      // 页面开始加载时重置弹窗标志位,保证下次触发正常
      _hasShownSearchAlert = false;
    });
  },
  onLoadStop: (controller, url) async {
    final urlStr = url.toString();
    // 仅当命中搜索路由且未弹出过弹窗时执行逻辑
    if (urlStr.contains('#/search') && !_hasShownSearchAlert) {
      setState(() {
        _hasShownSearchAlert = true;
      });
      await showDialog(
        context: context,
        barrierDismissible: false, // 防止点击空白关闭弹窗却不返回页面
        builder: (BuildContext context) {
          return AlertDialog(
            content: const Text('You can`t use search!'),
            actions: <Widget>[
              TextButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.of(context).pop();
                  // 调用WebView控制器返回上一页
                  controller.goBack();
                },
              )
            ],
          );
        },
      );
    }
    setState(() {
      isLoading = false;
    });
  },
  onProgressChanged: (controller, progress) {
    if (progress == 100) {
      setState(() {
        isLoading = false;
      });
    }
  },
),

核心修改说明

  • 用_hasShownSearchAlert标志位严格控制弹窗触发次数,避免重复回调导致的多次弹窗
  • 在onLoadStart中重置标志位,确保每次进入搜索路由都能正常触发逻辑
  • 替换原TODO的返回逻辑,直接调用controller.goBack()实现WebView页面返回
  • 添加barrierDismissible: false,避免用户误操作关闭弹窗却停留在搜索页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:15:01