Flutter 如何从 AlertDialog 菜单正确导航到新页面?
数据阿明
结论
问题出在导航操作的顺序:示例先调用 Navigator.pushNamed 打开第二个页面,随后又调用 Navigator.pop。如果两个操作使用同一个 Navigator,第二次调用会弹出刚打开的第二个页面,所以看起来导航没有生效,对话框也仍留在屏幕上。
先关闭对话框,再打开目标页面即可。
修改菜单项的点击处理
在 main.dart 的 ListTile.onTap 中调整调用顺序:
onTap: () {
Navigator.pop(dialogContext); // 先关闭 AlertDialog
Navigator.pushNamed(navigatorContext, "/second"); // 再打开目标页面
},
dialogContext 来自 showDialog 的 builder,用于关闭对话框。navigatorContext 是页面的 BuildContext,用于通过 MaterialApp 中注册的 "/second" 路由打开 MySecondPage。
关键结构如下:
void _showMyContextMenu(BuildContext listTileContext) {
final navigatorContext = this.context;
showDialog(
context: listTileContext,
builder: (BuildContext dialogContext) {
return AlertDialog(
title: Text(
"Context Menu",
style: TextStyle(
color: Theme.of(navigatorContext).colorScheme.primary,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: const Text('Goto second page.'),
onTap: () {
Navigator.pop(dialogContext);
Navigator.pushNamed(navigatorContext, "/second");
},
),
],
),
);
},
);
}
为什么要先关闭对话框
Navigator.pushNamed 会将目标路由推到导航栈顶。之后调用 Navigator.pop,弹出的就是当前栈顶路由。如果第二个页面已经推入栈顶,pop 就会将它移除,而不是关闭下面的对话框。
按调整后的顺序,Navigator.pop(dialogContext) 先移除对话框,接着 Navigator.pushNamed(navigatorContext, "/second") 打开第二个页面。示例中的 MaterialApp 已注册 "/second" 并将其映射到 MySecondPage,因此无需更改路由表。
注意事项
如果应用使用嵌套的 Navigator,请确认打开对话框和推入目标页面时使用的是预期的导航器。题目中的单个 MaterialApp 路由结构按上述顺序调用即可。
备注:内容仅供参考。
