Flutter中关闭CupertinoAlertDialog时页面弹出但弹窗残留问题
解决CupertinoAlertDialog关闭时页面被pop但弹窗残留的问题
我帮你分析下这个问题的核心原因:你调用Navigator.pop(context)时用的是页面本身的BuildContext,而不是弹窗内部的专属context。因为CupertinoAlertDialog是通过showCupertinoDialog作为独立路由弹出的,它属于单独的路由栈层级,用页面的context去pop会把页面路由从栈中移除,但弹窗的路由还留在栈顶,就出现了页面消失、弹窗还在的诡异情况。
下面给你两种靠谱的解决办法:
办法1:用弹窗内部的context关闭弹窗
当你用showCupertinoDialog创建弹窗时,builder函数会提供一个属于弹窗自己的BuildContext,用这个context调用Navigator.pop()就能精准关闭弹窗,不会影响页面:
if (deviceList.isEmpty) { showCupertinoDialog( context: context, // 这里用页面的context启动弹窗 builder: (dialogContext) { // 这个是弹窗内部的专属context return CupertinoAlertDialog( title: Text("Alert"), content: Text("There was an error signing in. Please try again."), actions: <Widget>[ CupertinoDialogAction( child: const Text('Discard'), isDestructiveAction: true, onPressed: () { Navigator.pop(dialogContext); // 用弹窗的context关闭弹窗 }, ), // 其他操作按钮可以同理处理 ], ); }, ); }
办法2:用rootNavigator确保操作弹窗路由
如果不确定context的层级关系,还可以指定操作根导航器,这样能确保你pop的是最顶层的弹窗路由,不会误操作页面:
CupertinoDialogAction( child: const Text('Discard'), isDestructiveAction: true, onPressed: () { Navigator.of(context, rootNavigator: true).pop('Discard'); }, ),
另外还要提个醒:千万别直接把CupertinoAlertDialog插到页面的Widget树里显示,这种方式不符合Flutter弹窗的使用规范,一定要用showCupertinoDialog或showDialog这类官方方法来弹出,它们会自动管理弹窗的路由层级,避免出现类似的奇怪问题。
内容的提问来源于stack exchange,提问作者Chaythanya Nair
相关产品推荐
相关产品推荐

