You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中使用go_router从子路由向根导航器推送页面的方法

解决GoRouter中推送独立页面到根导航器并保留Shell路由栈的问题

核心思路

通过区分根导航器和Shell导航器的层级,将独立页面绑定到根导航器,使其叠加在带底部导航栏的Shell路由之上,同时保留Shell的路由栈,返回时自动回到原Shell子页面。

具体实现步骤

1. 定义导航器Key

先分别定义根导航器和Shell导航器的全局Key,用于区分两个导航层级:

final GlobalKey<NavigatorState> _rootNavigatorKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> _shellNavigatorKey = GlobalKey<NavigatorState>();

2. 配置GoRouter路由

在路由配置中,将Shell路由绑定到Shell导航器Key,独立页面绑定到根导航器Key:

final GoRouter _router = GoRouter(
  navigatorKey: _rootNavigatorKey, // 根导航器作为默认导航器
  initialLocation: '/home',
  routes: [
    // Shell路由:包含底部导航栏,内部子路由使用Shell导航器
    ShellRoute(
      navigatorKey: _shellNavigatorKey,
      builder: (context, state, child) {
        return BottomNavBarScreen(child: child); // 你的底部导航栏页面
      },
      routes: [
        GoRoute(
          path: '/home',
          builder: (context, state) => const HomeScreen(),
        ),
        GoRoute(
          path: '/profile',
          builder: (context, state) => const ProfileScreen(),
        ),
        // 其他Shell子路由...
      ],
    ),
    // 独立页面:指定父导航器为根导航器,跳转时直接加入根栈
    GoRoute(
      path: '/independent-page',
      parentNavigatorKey: _rootNavigatorKey,
      builder: (context, state) => const IndependentPage(),
    ),
  ],
);

3. 跳转独立页面

在任意Shell子页面中,直接使用context.push跳转即可:

// 在HomeScreen/ProfileScreen中触发跳转
ElevatedButton(
  onPressed: () => context.push('/independent-page'),
  child: const Text('打开独立页面'),
)

替代方案(灵活控制跳转)

如果不想在路由配置中固定独立页面的导航器,也可以在跳转时通过rootNavigator: true参数指定使用根导航器:

context.push('/independent-page', rootNavigator: true);

为什么之前的方法会出现空白页

你之前移除所有路由再推送的操作,会清空根导航器的路由栈,导致返回时栈内没有页面,从而显示空白。而上述方案是在根栈中新增页面,Shell的路由栈始终保留,返回时自然回到原Shell子页面。

内容的提问来源于stack exchange,提问作者Zemichael Tesfaye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:10:56