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

Flutter 3.7升级3.24后PopScope返回传值报错求助

解决Flutter 3.24中PopScope替代WillPopScope时的!_debugLocked断言错误

问题原因

你遇到的!_debugLocked断言错误,是因为PopScope的onPopInvokedWithResult回调是在导航栈pop操作已经触发或执行中被调用的,此时Navigator处于锁定状态,不允许再次调用Navigator.pop()。这和旧版WillPopScope的逻辑完全不同——WillPopScope是在pop操作发起前询问是否允许,而PopScope的回调是pop过程中的通知,不能在里面重复触发pop。

正确实现方案

根据你的场景(返回时传递状态给前一页,触发数据重载),分两种情况处理:

1. 处理用户主动点击返回按钮(AppBar返回键)

直接在按钮点击事件中传递结果,不需要依赖onPopInvokedWithResult:

PopScope(
  child: Scaffold(
    appBar: AppBar(
      leading: IconButton(
        icon: const Icon(Icons.arrow_back),
        onPressed: () {
          // 主动返回时传递hasChanged状态
          Navigator.pop(context, hasChanged);
        },
      ),
    ),
    // 页面其他内容
  ),
)

2. 处理Android物理返回键(系统返回)

如果需要拦截系统返回并传递自定义结果,需要将canPop设为false,然后在onPopInvokedWithResult中主动触发pop(此时不会触发锁定,因为默认pop被拦截,我们是主动发起新的pop操作):

PopScope(
  canPop: false, // 禁止默认的系统返回行为
  onPopInvokedWithResult: (didPop, result) {
    // didPop为false表示系统尝试pop但被我们拦截
    if (!didPop) {
      Navigator.pop(context, hasChanged);
    }
  },
  child: Scaffold(
    // 页面内容
  ),
)

前一页接收结果代码(无需修改)

var hasChanged = await context.pushNamed(ApplicationRouteName.secondScreen);
if(hasChanged is bool){
  _handleReload();
}

核心逻辑说明

  • PopScope的canPop用于控制是否允许默认的pop操作(包括系统返回和AppBar默认返回键)
  • onPopInvokedWithResult是pop操作完成后的通知回调,不能在里面再次调用Navigator.pop(),除非是拦截了默认pop后主动发起的新pop
  • 传递返回值的核心是在Navigator.pop()时传入参数,而不是依赖回调传递

内容的提问来源于stack exchange,提问作者Trần Văn Hiếu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 19:51:02