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
相关产品推荐
相关产品推荐

