Flutter go_router嵌套路由设计

在Flutter中使用go_router实现嵌套路由时遇到几个问题:

  1. 如何正确配置父路由和子路由的路径结构?官方文档的嵌套示例比较基础,实际项目中多层嵌套时容易混乱。
  2. 子路由页面如何共享父路由的AppBar或BottomNavigationBar等布局组件?是否需要每个子页面重复编写这部分UI?
  3. 当深层嵌套路由跳转时,URL路径变得冗长,有没有办法简化或动态生成路由路径?
  4. 嵌套路由的转场动画如何自定义?默认的MaterialPageTransition不太符合设计需求。
  5. 在子路由中调用context.pop()时,如何控制是退出当前子路由还是整个父路由栈?

更多关于Flutter go_router嵌套路由设计的实战教程也可以访问 https://www.itying.com/category-92-b0.html

3 回复

在Flutter中使用go_router实现嵌套路由设计时,首先需要定义路由树结构。比如一个典型的嵌套场景:App有底部导航栏,每个Tab页又有自己的子页面。

  1. 首先安装go_router:dependencies: go_router: ^x.x.x

  2. 定义主路由和子路由:

final GoRouter _router = GoRouter(
  routes: [
    // 主路由
    StatefulShellRoute.indexedStack(
      branches: [
        // Tab1分支
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/tab1',
              builder: (context, state) => Tab1Page(),
              routes: [
                // 子路由
                GoRoute(
                  path: 'sub1',
                  builder: (context, state) => Sub1Page(),
                ),
              ],
            ),
          ],
        ),
        // 其他Tab类似定义...
      ],
      builder: (context, state, navigationShell) {
        return MainLayout(navigationShell: navigationShell);
      },
    ),
  ],
);
  1. 在MainLayout中通过navigationShell来展示当前选中的Tab及其子页面。

这种方式可以清晰地组织路由结构,保持代码整洁。记得在每个页面中用context.go()context.push()来进行导航操作。

更多关于Flutter go_router嵌套路由设计的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中使用go_router进行嵌套路由设计时,首先需要定义嵌套的路由树结构。例如,一个App可能有首页、用户中心和设置页面,其中用户中心又包含个人资料和订单列表两个子页面。

final GoRouter _router = GoRouter(
  routes: [
    StatefulShellRoute.indexedStack(
      branches: [
        UserBranch(),
        SettingsBranch(),
      ],
      builder: (context, state, navigationShell) {
        return ScaffoldWithBottomNavBar(navigationShell: navigationShell);
      },
    ),
  ],
);

每个分支(branch)代表一个导航壳体,比如用户中心这个分支可以这样定义:

class UserBranch extends Branch {
  @override
  List<GoRoute> get routes => [
        GoRoute(
          path: '/profile',
          builder: (context, state) => ProfilePage(),
        ),
        GoRoute(
          path: '/orders',
          builder: (context, state) => OrdersPage(),
        ),
      ];
}

这样,当你访问/user/profile/user/orders时,都会加载到用户中心的导航壳体内。通过这种方式,你可以轻松地构建出复杂的嵌套路由结构,并且保持代码的清晰与可维护性。

Flutter go_router 嵌套路由设计

go_router 是 Flutter 中一个流行的路由管理库,它支持嵌套路由设计,可以创建复杂的导航结构。下面介绍如何使用 go_router 实现嵌套路由。

基本嵌套路由配置

final router = GoRouter(
  routes: [
    // 顶层路由
    GoRoute(
      path: '/',
      builder: (context, state) => const HomeScreen(),
      routes: [
        // 嵌套路由
        GoRoute(
          path: 'products',
          builder: (context, state) => const ProductsScreen(),
          routes: [
            // 更深层嵌套
            GoRoute(
              path: ':id',
              builder: (context, state) => ProductDetailScreen(
                id: state.params['id']!,
              ),
            ),
          ],
        ),
      ],
    ),
  ],
);

嵌套路由的 Shell 路由

对于需要在不同子路由间共享相同布局的情况,可以使用 ShellRoute:

final router = GoRouter(
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return Scaffold(
          appBar: AppBar(title: Text('My App')),
          body: child,
        );
      },
      routes: [
        GoRoute(
          path: '/',
          builder: (context, state) => const HomeScreen(),
        ),
        GoRoute(
          path: '/settings',
          builder: (context, state) => const SettingsScreen(),
        ),
      ],
    ),
  ],
);

带底部导航的嵌套路由

final router = GoRouter(
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return Scaffold(
          body: child,
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: _calculateSelectedIndex(state),
            onTap: (index) => _onItemTapped(index, context),
            items: const [
              BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
              BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'),
            ],
          ),
        );
      },
      routes: [
        GoRoute(
          path: '/',
          builder: (context, state) => const HomeScreen(),
        ),
        GoRoute(
          path: '/settings',
          builder: (context, state) => const SettingsScreen(),
        ),
      ],
    ),
  ],
);

使用 StatefulShellRoute

go_router 还提供了 StatefulShellRoute 来维护不同分支的状态:

final router = GoRouter(
  routes: [
    StatefulShellRoute.indexedStack(
      builder: (context, state, navigationShell) {
        return Scaffold(
          body: navigationShell,
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: navigationShell.currentIndex,
            onTap: navigationShell.goToBranch,
            items: const [
              BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
              BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'),
            ],
          ),
        );
      },
      branches: [
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/',
              builder: (context, state) => const HomeScreen(),
            ),
          ],
        ),
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/settings',
              builder: (context, state) => const SettingsScreen(),
            ),
          ],
        ),
      ],
    ),
  ],
);

以上展示了 go_router 中实现嵌套路由的几种主要方式,你可以根据应用需求选择最适合的方案。

回到顶部