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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:55:15