使用Flutter GoRouter的StatefulShellRoute.indexedStack时,NavigationBar选中索引点击Tab不更新问题求助
大家好,我最近在用Flutter开发应用,用go_router做路由管理,StatefulShellRoute.indexedStack来实现底部导航栏,但是遇到了一个棘手的问题:点击底部导航栏的Tab项时,selectedIndex不会更新,UI也完全没反应。
先给大家贴一下我的简化代码结构,方便排查:
导航键定义
// === NavigatorKey group =============================================== final _rootNavKey = GlobalKey<NavigatorState>(debugLabel: 'root'); final _libraryNavKey = GlobalKey<NavigatorState>(debugLabel: 'lib'); final _analysisNavKey = GlobalKey<NavigatorState>(debugLabel: 'analysis'); final _calendarNavKey = GlobalKey<NavigatorState>(debugLabel: 'calendar');
Riverpod的Router Provider
// === Riverpod Provider ================================================= final routerProvider = Provider<GoRouter>((ref) { final auth = ref.watch(authStateChangesProvider); return GoRouter( navigatorKey: _rootNavKey, initialLocation: AppRoutes.authSelection.path, // ---------- Authentication block (no BottomNav) ---------- routes: [ GoRoute( path: AppRoutes.authSelection.path, name: AppRoutes.authSelection.name, parentNavigatorKey: _rootNavKey, builder: (_, __) => const AuthSelectionScreen(), routes: [ GoRoute( path: AppRoutes.signin.path, name: AppRoutes.signin.name, builder: (_, __) => const SignInScreen(), ), GoRoute( path: AppRoutes.signup.path, name: AppRoutes.signup.name, builder: (_, __) => const SignUpScreen(), ), ], ), // ---------- Main app with BottomNav ---------- StatefulShellRoute.indexedStack( parentNavigatorKey: _rootNavKey, builder: (context, state, navShell) => AppNavigationBar(navigationShell: navShell), branches: [ // ---- Branch 0: MyLibrary ---- StatefulShellBranch( //initialLocation: AppRoutes.myLibrary.path, navigatorKey: _libraryNavKey, routes: [ GoRoute( path: AppRoutes.myLibrary.path, name: AppRoutes.myLibrary.name, builder: (_, __) => const MyLibraryScreen(), ), ], ), // ---- Branch 1: Analysis ---- StatefulShellBranch( //initialLocation: AppRoutes.analysis.path, navigatorKey: _analysisNavKey, routes: [ GoRoute( path: AppRoutes.analysis.path, name: AppRoutes.analysis.name, builder: (_, __) => const AnalysisScreen(), ), ], ), // ---- Branch 2: Calendar ---- StatefulShellBranch( //initialLocation: AppRoutes.calendar.path, navigatorKey: _calendarNavKey, routes: [ GoRoute( path: AppRoutes.calendar.path, name: AppRoutes.calendar.name, builder: (_, __) => const CalendarScreen(), ), ], ), ], ), ], // ---------- Authentication redirect ---------- redirect: (_, state) { if (auth.isLoading || auth.hasError) return null; final loggedIn = auth.valueOrNull != null; final inAuth = state.matchedLocation.startsWith( AppRoutes.authSelection.path, ); if (!loggedIn && !inAuth) return AppRoutes.authSelection.path; if (loggedIn && inAuth) return AppRoutes.myLibrary.path; return null; }, ); });
底部导航栏组件
import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; final class AppNavigationBar extends StatelessWidget { const AppNavigationBar({super.key, required this.navigationShell}); final StatefulNavigationShell navigationShell; @override Widget build(BuildContext context) { return Scaffold( body: navigationShell, bottomNavigationBar: NavigationBar( selectedIndex: navigationShell.currentIndex, destinations: const [ NavigationDestination(icon: Icon(Icons.home), label: 'MyLibrary'), NavigationDestination(icon: Icon(Icons.favorite), label: 'Analysis'), NavigationDestination( icon: Icon(Icons.calendar_today), label: 'Calendar', ), ], onDestinationSelected: (index) { // Only navigate if index is different from current if (index != navigationShell.currentIndex) { navigationShell.goBranch(index); debugPrint( 'Selected index: $index, Current index: ${navigationShell.currentIndex}', ); } }, ), ); } }
问题详情
我已经做了这些检查:
- 确认在Tab选中时调用了
navigationShell.goBranch(index) - 每个
StatefulShellBranch都设置了唯一的navigatorKey - 初始路由配置正确
但点击Tab时,selectedIndex就是不更新,页面内容也切换不了。有没有大佬能帮我分析下可能的原因?非常感谢!
内容来源于stack exchange




