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

Flutter中使用auto_route:^7.4.0实现持久化底部导航栏求助

解决auto_route实现持久化底部导航栏的问题

问题分析

你的代码存在两个核心问题:

  • 路由配置冲突:DashBoardRoute和HomeTabRoute的path都设为"/",导致路由解析混乱,底部导航容器无法正确作为根页面加载。
  • 路由层级错误:HomeTabRoute的子路由配置未与AutoTabsScaffold的routes对应,导致页面切换时底部导航栏被覆盖。

解决方案步骤

1. 修正路由配置

调整AppRouter的路由结构,将底部导航容器HomeTabRoute设为验证后的根页面,移除重复的根路径配置:

@AutoRouterConfig()
class AppRouter extends _$AppRouter {
  @override
  final List<AutoRoute> routes = [
    // 登录与引导页面
    AutoRoute(page: SplashRoute.page, path: "/splash"),
    AutoRoute(page: RegistrationSuccessfulRoute.page, path: "/registration_successful"),
    AutoRoute(page: RegistrationRoute.page, path: "/registration"),
    AutoRoute(page: LoginRoute.page, path: "/loginPage"),
    AutoRoute(page: VerifyOtpRoute.page, path: "/verifyOtp"),
    AutoRoute(page: LanguageSelectionRoute.page, path: "/languageSelect"),
    AutoRoute(page: OnBoardSelectEntrepreneurRoute.page, path: "/onboard_select_entrepreneur"),
    AutoRoute(page: OnBoardPreparingDataRoute.page, path: "/onboard_prepare_data"),

    // 独立页面(从底部导航跳转的页面)
    AutoRoute(page: NotificationRoute.page, path: "/notifications"),
    AutoRoute(page: CourseDetailRoute.page, path: "/course_detail"),
    AutoRoute(page: VideoBuilderRoute.page, path: "/video_player/:arguments"),
    AutoRoute(page: BundleCourseRoute.page, path: "/bundle_course_page"),

    // 底部导航容器(验证后的根页面)
    AutoRoute(
      page: HomeTabRoute.page, 
      path: "/", 
      guards: [AuthGuard()],
      children: [
        CustomRoute(page: HomeRoute.page, path: "home", children: [
          AutoRoute(page: VideoPlayRoute.page, path: "video-play/:arguments"),
        ]),
        CustomRoute(page: SearchRoute.page, path: "search"),
        CustomRoute(page: CoursesRoute.page, path: "courses"),
        CustomRoute(page: ProfileRoute.page, path: "profile"),
      ],
    ),

    // 管理员页面
    AutoRoute(page: AdminCourseListRoute.page, path: "/admin_course_list"),
    AutoRoute(page: AdminAddLessonRoute.page, path: "/admin_add_lesson_page"),
    AutoRoute(page: AdminAddCourseRoute.page, path: "/admin_add_course_page"),

    RedirectRoute(path: '*', redirectTo: '/'),
  ];
}

2. 修正AutoTabsScaffold实现

确保AutoTabsScaffold的routes与路由配置中的子路由完全对应,同时优化返回栈逻辑:

class HomeTabRoute extends StatelessWidget {
  const HomeTabRoute({super.key});

  @override
  Widget build(BuildContext context) {
    final backStack = <int>[0]; // 初始化返回栈,默认选中首页

    return AutoTabsScaffold(
      // 对应路由配置中的子路由类
      routes: const [
        HomeRoute(),
        SearchRoute(),
        CoursesRoute(),
        ProfileRoute(),
      ],
      bottomNavigationBuilder: (_, tabsRouter) {
        // 监听当前索引变化,维护返回栈
        void updateBackStack(int newIndex) {
          if (backStack.last != newIndex) {
            backStack.add(newIndex);
          }
        }

        return WillPopScope(
          onWillPop: () async {
            if (tabsRouter.activeIndex != 0) {
              if (backStack.length > 1) {
                backStack.removeLast();
                final previousIndex = backStack.last;
                tabsRouter.setActiveIndex(previousIndex);
                return false; // 阻止应用退出
              }
              // 当返回栈只剩首页时,允许退出
              return true;
            }
            backStack.clear();
            backStack.add(0);
            return true;
          },
          child: Container(
            height: 72,
            decoration: buildYellowBoxDecoration(),
            child: Padding(
              padding: const EdgeInsets.only(top: 6.0),
              child: Container(
                decoration: buildGreenBoxDecoration(),
                child: ClipRRect(
                  borderRadius: const BorderRadius.only(
                    topRight: Radius.circular(20),
                    topLeft: Radius.circular(20),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.only(top: 8.0),
                    child: BottomNavigationBar(
                      currentIndex: tabsRouter.activeIndex,
                      onTap: (index) {
                        updateBackStack(index);
                        tabsRouter.setActiveIndex(index);
                      },
                      items: [
                        BottomNavigationBarItem(
                          icon: Image.asset(homeIcon),
                          activeIcon: Image.asset(homeIconActive),
                          label: '首页',
                        ),
                        BottomNavigationBarItem(
                          icon: Image.asset(searchIcon),
                          activeIcon: Image.asset(searchIconActive),
                          label: '搜索',
                        ),
                        BottomNavigationBarItem(
                          icon: Image.asset(coursesIcon),
                          activeIcon: Image.asset(coursesIconActive),
                          label: '课程',
                        ),
                        BottomNavigationBarItem(
                          icon: Image.asset(profileIcon),
                          activeIcon: Image.asset(profileIconActive),
                          label: '我的',
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
        );
      },
    );
  }

  // 保留你的buildYellowBoxDecoration和buildGreenBoxDecoration方法
  BoxDecoration buildYellowBoxDecoration() => BoxDecoration(/* 你的原有实现 */);
  BoxDecoration buildGreenBoxDecoration() => BoxDecoration(/* 你的原有实现 */);
}

3. 关键注意事项

  • 所有从底部导航页面跳转的子页面(如VideoPlayRoute)必须作为对应tab路由的子路由配置,这样跳转时底部导航栏会保持可见。
  • 使用AutoTabsRouter.of(context)可以在任意子页面中获取底部导航的路由控制器,实现跨页面切换tab的需求。
  • 确保运行flutter pub run build_runner build重新生成路由代码,避免配置不生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:05:24