PAYATHON 2026

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 路由结构按上述顺序调用即可。

备注:内容仅供参考。