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

Flutter中GoRouter实现无限导航并保留BottomNavigationBar的方案咨询

Flutter go_router 保留BottomNavigationBar同时实现无限导航循环的解决方案

核心思路

要同时实现无限嵌套的导航循环(post→user→post…)和保留BottomNavigationBar,关键是把需要复用的post/user路由定义抽离出来,作为StatefulShellBranch的共享子路由挂载,既避免重复代码,又确保所有页面都处于底部栏所在的导航栈中。

实现代码

首先抽离复用的路由逻辑,通过循环引用实现无限嵌套结构:

// 复用的Post路由,包含嵌套的User及后续循环路由
final postRoute = GoRoute(
  path: 'post/:postId',
  pageBuilder: (context, state) {
    final postId = state.pathParameters['postId']!;
    return MaterialPage(child: PostScreen(postId: postId));
  },
  routes: [
    // 嵌套的User路由
    GoRoute(
      path: 'user/:userId',
      pageBuilder: (context, state) {
        final userId = state.pathParameters['userId']!;
        return MaterialPage(child: UserScreen(userId: userId));
      },
      routes: [
        postRoute, // 循环引用,实现post→user→post的无限导航
        // FeedCollectionUser路由
        GoRoute(
          path: 'feedcollectionuser/:collectionId',
          pageBuilder: (context, state) {
            final collectionId = state.pathParameters['collectionId']!;
            return MaterialPage(child: FeedCollectionUserScreen(id: collectionId));
          },
          routes: [
            postRoute, // 继续嵌套Post,保持循环结构
          ],
        ),
      ],
    ),
  ],
);

然后在StatefulShellRoute的分支中挂载这个复用路由:

GoRouter createRouter(BuildContext context) {
  final authBloc = context.read<AuthBloc>();

  return GoRouter(
    navigatorKey: _rootNavigatorKey,
    debugLogDiagnostics: true,
    initialLocation: '/home',
    routes: <RouteBase>[
      StatefulShellRoute.indexedStack(
        builder: (context, state, navigationShell) {
          return ScaffoldWithNavBar(
            currentLocation: state.uri.toString(),
            navigationShell: navigationShell,
            userIdFromAuth: authBloc.state.user!.uid,
            appBar: null,
          );
        },
        branches: <StatefulShellBranch>[
          // Home分支
          StatefulShellBranch(
            routes: <RouteBase>[
              GoRoute(
                path: '/home',
                pageBuilder: (context, state) {
                  return MaterialPage(child: HomeScreen());
                },
                routes: [
                  postRoute, // 挂载复用的Post路由
                ],
              ),
            ],
          ),
          // Feed分支
          StatefulShellBranch(
            routes: <RouteBase>[
              GoRoute(
                path: '/feed',
                pageBuilder: (context, state) {
                  return MaterialPage(child: FeedScreen());
                },
                routes: [
                  postRoute, // 同样挂载复用路由
                ],
              ),
            ],
          ),
        ],
      ),
    ],
  );
}

方案优势

  • 路径简洁且符合需求:路由结构完全匹配你期望的嵌套层级,比如/home/post/123/user/456/post/789
  • 组件/路由复用:只需要定义一次post/user路由逻辑,即可在Home和Feed分支中共享
  • 保留BottomNavigationBar:所有页面都处于StatefulShell的分支导航栈内,底部栏始终可见
  • 完整导航历史:每次跳转都会添加到当前分支的导航栈,返回操作按顺序退栈,完美支持无限循环跳转

补充说明

如果需要跨分支跳转(比如从Home的post跳转到Feed的post),直接使用context.go('/feed/post/${targetPostId}')即可,此时会自动切换到Feed分支并加载对应页面,底部栏也会同步切换到Feed标签。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:57:38