You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Flutter GoRouter的StatefulShellRoute.indexedStack时,NavigationBar选中索引点击Tab不更新问题求助

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

火山引擎 最新活动