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
相关产品推荐
相关产品推荐

