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

Flutter中第二次点击PopupMenuButton菜单项触发navigator断言失败求助

解决Flutter PopupMenuButton点击菜单项第二次触发导航断言错误的问题

嘿,我来帮你搞定这个头疼的问题!你遇到的这个'package:flutter/src/widgets/navigator.dart': Failed assertion: line 1846 pos 12: '!_debugLocked': is not true异常,是Flutter导航框架里的典型场景问题——在导航状态被锁定时尝试发起新的导航操作,而PopupMenuButton的点击回调刚好容易踩这个坑。

问题原因

当你点击PopupMenu的菜单项时,框架会自动触发弹窗关闭的逻辑,这个过程中会临时锁定导航状态(把_debugLocked设为true)。如果你的onSelected回调里直接调用Navigator.push这类导航方法,第一次点击可能刚好“卡”在锁定前执行成功,但第二次点击时,弹窗关闭的锁定逻辑和你的导航操作撞在了一起,就触发了这个断言错误。

解决方案

核心思路就是延迟导航操作,等弹窗完全关闭、导航状态解锁后再执行,这里给你两种靠谱的实现方式:

方式1:使用addPostFrameCallback(推荐)

这个方法会在当前Widget树的构建、布局、绘制全部完成后再执行回调,完美避开弹窗关闭的锁定周期:

onSelected: (PopupMenuChoice choice) {
  WidgetsBinding.instance.addPostFrameCallback((_) {
    Navigator.push(context, choice.pageRoute);
  });
},

方式2:使用Future.delayed(Duration.zero)

这也是一种延迟执行的方式,效果和上面类似,本质是把导航操作放到下一个事件循环里:

onSelected: (PopupMenuChoice choice) {
  Future.delayed(Duration.zero, () {
    Navigator.push(context, choice.pageRoute);
  });
},

完整代码示例

结合你定义的PopupMenuChoice类,完整的使用示例如下:

class PopupMenuChoice {
  const PopupMenuChoice({this.title, this.pageRoute});
  final String title;
  final MaterialPageRoute pageRoute;
}

// 在你的Widget构建方法里使用PopupMenuButton
PopupMenuButton<PopupMenuChoice>(
  itemBuilder: (BuildContext context) => <PopupMenuEntry<PopupMenuChoice>>[
    PopupMenuItem<PopupMenuChoice>(
      value: PopupMenuChoice(
        title: "我的页面",
        pageRoute: MaterialPageRoute(builder: (_) => const MyTargetPage()),
      ),
      child: const Text("我的页面"),
    ),
    // 可以添加更多菜单项
  ],
  onSelected: (PopupMenuChoice choice) {
    // 用推荐的方式延迟导航
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Navigator.push(context, choice.pageRoute);
    });
  },
)

额外提醒

作为Flutter新手,要多留意框架的状态更新时机——很多这类断言错误,都是因为在框架正在处理状态变更(比如弹窗关闭、组件重建)的时候,发起了新的状态或导航操作,延迟执行是解决这类问题的常用技巧哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:02:24