Flutter中GoRouter嵌套StatefulShellRoute实现独立导航栏问题求助
解决GoRouter嵌套StatefulShellRoute的问题
错误原因分析
- 路由结构错误:原代码将
StatefulShellRoute直接作为/leagues这个GoRoute的子路由,但StatefulShellRoute是用于构建多分支导航的顶层路由组件,不能嵌套在普通GoRoute的子路由列表中。 - 参数获取逻辑错误:嵌套
StatefulShellRoute的builder中尝试获取tournamentId,但该参数仅存在于details/:tournamentId路径中,外层/leagues路由无此参数,直接访问会触发空指针异常。
修正方案
调整路由结构,将/leagues分支改为嵌套的StatefulShellRoute,并正确处理参数传递:
@riverpod GoRouter goRouter(GoRouterRef ref) { return GoRouter( initialLocation: '/matches', routes: [ StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) { return ScaffoldWithNestedNavigation(navigationShell: navigationShell); }, branches: [ // Leagues分支:嵌套独立的StatefulShellRoute StatefulShellBranch(routes: [ StatefulShellRoute.indexedStack( path: '/leagues', builder: (context, state, navigationShell) { // 从当前导航栈的路由状态中获取tournamentId,处理空值 final tournamentId = navigationShell.currentState?.pathParameters['tournamentId'] ?? ''; return LeagueScaffoldNestedNavigation( navigationShell: navigationShell, tournamentId: tournamentId, ); }, branches: [ StatefulShellBranch(routes: [ // 对应/leagues路径 GoRoute( path: '', pageBuilder: (context, state) => NoTransitionPage(child: LeaguesScreen()), ), // 对应/leagues/details/:tournamentId路径 GoRoute( name: 'details', path: 'details/:tournamentId', pageBuilder: (context, state) { return NoTransitionPage( child: MatchesScreen(tournamentId: state.pathParameters['tournamentId']!), ); }, ), ]), ], ), ]), // Matches分支(保持原逻辑) StatefulShellBranch(routes: [ GoRoute( path: '/matches', pageBuilder: (context, state) => const NoTransitionPage(child: TodaysMatchScreen()), routes: [ GoRoute( path: "live", pageBuilder: (context, state) => const NoTransitionPage(child: LiveScreen()), ), ], ), ]), // Favorites分支(保持原逻辑) StatefulShellBranch(routes: [ GoRoute( path: '/favorites', pageBuilder: (context, state) => const NoTransitionPage(child: FavoritesMatchScreen()), ), ]), ], ), ], ); }
关键调整点
- 将
/leagues分支的路由从GoRoute替换为嵌套的StatefulShellRoute.indexedStack,使其成为外层多分支导航的独立子导航结构。 - 在嵌套
StatefulShellRoute的builder中,通过navigationShell.currentState动态获取当前路由的参数,避免空指针。 - 将
/leagues和/leagues/details/:tournamentId作为嵌套StatefulShellRoute的分支路由,确保导航结构层级正确。
内容的提问来源于stack exchange,提问作者Abel
相关产品推荐
相关产品推荐

