我正在从另一个对话框打开一个对话框,并试图关闭第一个对话框,但它正在关闭最近的对话框。类似的git issue。
我试过了
- 将
ValueKey
放在AlertDialog
上 - 使用
rootNavigator:true
while pop - 将
context
保存到变量中并执行Navigator.of(specifiqContext).pop()
但是它们都不起作用。在dartPad上重现这个问题的代码。
class MultiDialogTest extends StatefulWidget {
const MultiDialogTest({Key? key}) : super(key: key);
@override
State<MultiDialogTest> createState() => _MultiDialogTestState();
}
class _MultiDialogTestState extends State<MultiDialogTest> {
BuildContext? dialog1Context, dialog2Context;
Future<void> _showDialog1(BuildContext context) async {
await showDialog(
context: context,
barrierDismissible: false,
builder: (c) {
dialog1Context = c;
return AlertDialog(
key: const ValueKey("dialog 1"),
title: const Text("Dialog 1"),
content: ElevatedButton(
child: const Text("close dialog2"),
onPressed: () {
if (dialog2Context != null) {
Navigator.of(dialog2Context!,).pop();
}
},
),
actions: [
ElevatedButton(
child: const Text("close this"),
onPressed: () {
Navigator.of(c, rootNavigator: true).pop();
},
),
],
);
});
dialog1Context = null;
}
Future<void> _showDialog2(BuildContext context) async {
await showDialog(
context: context,
barrierDismissible: false,
builder: (c) {
dialog2Context = c;
return AlertDialog(
key: const ValueKey("dialog 2"),
title: const Text("Dialog 2"),
actions: [
ElevatedButton(
child: const Text("close this"),
onPressed: () {
Navigator.of(c, rootNavigator: true).pop();
},
),
],
content: Column(
children: [
ElevatedButton(
onPressed: () async {
await _showDialog1(context);
},
child: const Text("Open dialog 1"),
),
],
),
);
});
dialog2Context = null;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
_showDialog2(context);
},
child: const Text("show dialog 2"),
),
),
);
}
}
如何关闭下面的对话框(Dialog 2
)而不关闭上面的对话框(Dialog 1
)。
我不喜欢关闭两者并重新打开Dialog 1
。
5条答案
按热度按时间yacmzcpb1#
你需要传递你想要关闭的对话框的上下文(parentContext)并调用:
xnifntxz2#
Navigator.pop(dialogContext);
下面是示例代码。
w6mmgewl3#
我看到仍然没有答案,所以我这样做了:
你也可以返回
myDialogRoute
并远程使用它。只要确保在处理上下文之前关闭对话框。chhqkbe14#
您可以在
showDialog1
中弹出两次,然后立即等待showDialog1
。vyu0f0g15#
当你使用
showDialog
时,在引擎盖下发生的事情是在导航器上的一个简单的推动,这将在当前Navigator
的顶部添加对话框作为一个新的路由。Navigator
中的所有pop方法都只是从最顶层的路由中弹出,因此这并不容易实现。一个肮脏的黑客可能是弹出两次,并再次显示第一个对话框一样,在这个例子中,工程在您的dartpad样本
在我看来,让一个对话框产生另一个对话框并不是你能为用户提供的最好的UX,但是你可以通过使用检查器来检查哪些路由涉及到:
https://docs.flutter.dev/development/tools/devtools/inspector
在这种情况下,你可以快速检查对话框是否总是在顶部(在这种情况下是树的最新部分),解决这个问题的正确方法应该是创建几个导航器,并决定使用哪个来显示你的对话框,但这会使你的代码变得复杂!