如何区分Flutter中的内外Context以正确关闭showDialog?
解决Flutter中showDialog关闭错误的问题
你遇到的问题核心是:调用Navigator.of(context).pop()时用的是页面的外层context,而非弹窗自身的context,所以会关闭页面而非弹窗。下面是两种简单可行的解决方法:
方法一:保存弹窗的Context
在State类中声明变量存储弹窗的context,在showDialog的builder中赋值,之后用这个context关闭弹窗:
// 在你的State类中添加变量 late BuildContext dialogContext; // 修改后的loading回调 loading: () { WidgetsBinding.instance.addPostFrameCallback((_) { showDialog( barrierDismissible: false, context: context, builder: (context) { // 保存弹窗专属的context dialogContext = context; return const Center( child: CircularProgressIndicator(), ); } ); }); }, // data回调中使用弹窗context关闭弹窗 data: (data){ if(mounted) Navigator.of(dialogContext).pop(); },
加上
mounted判断可避免State已销毁时调用pop引发异常。
方法二:使用rootNavigator参数
调用showDialog时指定useRootNavigator: true,之后在pop时传入rootNavigator: true参数,确保操作的是根导航器的弹窗:
// 修改showDialog的参数 showDialog( barrierDismissible: false, context: context, useRootNavigator: true, // 添加该参数 builder: (context) { return const Center( child: CircularProgressIndicator(), ); } ); // 修改data回调的pop方式 data: (data){ Navigator.of(context, rootNavigator: true).pop(); },
这种方法无需额外存储context,适合简单场景。
原代码出错原因
showDialog的builder会创建一个属于弹窗路由的新上下文(context),而你原代码data回调中使用的是外层页面的context,调用pop()时会关闭页面路由,而非弹窗路由。
内容的提问来源于stack exchange,提问作者SugiuraY
相关产品推荐
相关产品推荐

