如何在ShellRoute跳转至子路由时隐藏底部导航栏?
GoRouter实现嵌套路由下隐藏底部导航
问题描述
我想要创建如下导航结构:
|_ShellRoute |_GoRoute /a(需显示底部导航) |_GoRoute /a/nested/:id(无需显示底部导航) |_GoRoute /b(需显示底部导航) |_GoRoute /c(需显示底部导航)
但跳转到/a/nested/1时,底部导航仍然显示。我的类型安全路由代码如下(普通GoRouter也适用):
final rootNavigatorKey = GlobalKey<NavigatorState>(); final router = GoRouter( routes: $appRoutes, initialLocation: '/a', navigatorKey: rootNavigatorKey, ); final shellNavigatorKey = GlobalKey<NavigatorState>(); @TypedShellRoute<BottomShellRoute>(routes: [ TypedGoRoute<ARoute>(path: '/a', routes: [ TypedGoRoute<ANestedRoute>(path: 'nested/:id'), ]), TypedGoRoute<BRoute>(path: '/b'), TypedGoRoute<CRoute>(path: '/c'), ]) class BottomShellRoute extends ShellRouteData { const BottomShellRoute(); static final GlobalKey<NavigatorState> $navigatorKey = shellNavigatorKey; @override Widget builder(BuildContext context, GoRouterState state, Widget navigator) => BottomShellScreen( location: state.location, child: navigator, ); }
解决方案
有两种可靠的实现方式:
方法1:在Shell构建器中动态控制底部导航显示
修改BottomShellRoute的builder方法,通过当前路由路径判断是否隐藏底部导航,传递控制参数给BottomShellScreen:
@override Widget builder(BuildContext context, GoRouterState state, Widget navigator) { // 判断当前路径是否属于/a/nested/开头的子路由 final shouldHideBottomNav = state.location.startsWith('/a/nested/'); return BottomShellScreen( location: state.location, child: navigator, // 假设BottomShellScreen支持showBottomNav参数控制显示 showBottomNav: !shouldHideBottomNav, ); }
如果你的BottomShellScreen没有现成参数,可在其内部根据传入的location判断:
// BottomShellScreen的build方法 @override Widget build(BuildContext context) { final shouldHide = widget.location.startsWith('/a/nested/'); return Scaffold( body: widget.child, bottomNavigationBar: shouldHide ? null : YourBottomNavigationBar(), ); }
方法2:将嵌套路由挂载到根导航器
让/a/nested/:id直接使用根导航器,脱离Shell路由的包裹。修改类型安全路由定义,为ANestedRoute指定根导航器Key:
@TypedShellRoute<BottomShellRoute>(routes: [ TypedGoRoute<ARoute>(path: '/a', routes: [ TypedGoRoute<ANestedRoute>( path: 'nested/:id', // 指定使用根导航器,跳过Shell的底部导航 parentNavigatorKey: rootNavigatorKey, ), ]), TypedGoRoute<BRoute>(path: '/b'), TypedGoRoute<CRoute>(path: '/c'), ])
跳转至/a/nested/1时,页面会直接在根导航栈中渲染,不会包含Shell的底部导航栏。
内容的提问来源于stack exchange,提问作者Exprove
相关产品推荐
相关产品推荐

