Flutter中如何保证AlertDialog每次使用正确上下文自动消失
修复方案
优化后完整代码
showAlertDialogTMPCoinsAdded(BuildContext context, String title, String content) { Timer? timer; showDialog( barrierDismissible: false, context: context, // 统一使用根导航挂载弹窗,避免路由栈混乱 useRootNavigator: true, builder: (BuildContext dialogContext) { timer = Timer(const Duration(milliseconds: 1000), () { // 关闭前先校验弹窗是否还存在,避免抛出异常 if (dialogContext.mounted) { Navigator.of(dialogContext).pop(); } }); return AlertDialog( title: Text(title), content: Image.asset('assets/images/coins.gif'), ); }, // 弹窗任意方式关闭时都取消定时器,避免无效执行 ).then((_) => timer?.cancel()); }
核心优化点
- 改用弹窗专属的
dialogContext执行关闭:showDialog的builder参数提供的context仅属于当前弹窗路由,完全不会受外层Widget的生命周期影响,也不会出现误关其他页面、找不到匹配路由的问题 - 增加挂载状态校验:执行pop前先判断
dialogContext.mounted,如果弹窗已经被提前关闭,就跳过关闭逻辑,彻底避免路由匹配异常 - 统一根导航配置:
showDialog时指定useRootNavigator: true,保证弹窗始终挂载在根导航栈,和后续关闭操作的Navigator实例完全匹配
低版本Flutter兼容
如果你的项目使用的Flutter版本低于3.7,不支持context.mounted属性,可以将定时器内的判断逻辑替换为:
if (ModalRoute.of(dialogContext)?.isCurrent ?? false) { Navigator.of(dialogContext).pop(); }
内容的提问来源于stack exchange,提问作者Petro
相关产品推荐
相关产品推荐

