Flutter BottomNavigationBar跳转新页面后消失问题求助
问题分析与解决思路
核心问题
你的代码存在三个关键错误,直接导致底部导航栏跳转后消失:
- 错误的导航逻辑:使用
Navigator.pushNamed会将新页面推入导航栈顶部,直接覆盖包含BottomNavigationBar的原Scaffold,自然看不到底部导航栏。 - 嵌套
MaterialApp:根组件已经是MaterialApp,但你又在Scaffold的body里嵌套了MaterialApp.router,这会导致导航上下文冲突,且不符合Flutter单根MaterialApp的规范。 - 混合路由方式:同时配置了
routes命名路由和AutoRouter,两种路由系统混用会引发导航逻辑混乱。
解决步骤
1. 统一路由结构,移除嵌套的MaterialApp
将MaterialApp.router作为根组件,把原来带底部导航的Scaffold作为其home属性值,确保整个应用只有一个根导航上下文。
2. 切换页面内容而非跳转页面
底部导航的正确实现方式是在同一个Scaffold下切换body内容,而非跳转新页面。用你已在使用的Riverpod维护当前选中的导航索引,根据索引渲染对应页面。
3. 优化状态管理与页面切换
使用IndexedStack保持页面状态(切换时不重新初始化页面),如果不需要状态保持,也可以用条件判断直接返回对应页面。
修改后的代码示例
// 先定义状态Provider管理选中的导航索引 final selectedIndexProvider = StateProvider<int>((ref) => 0); @override Widget build(BuildContext context, WidgetRef ref) { final selectedIndex = ref.watch(selectedIndexProvider); final selectedIndexNotifier = ref.read(selectedIndexProvider.notifier); return MaterialApp.router( builder: EasyLoading.init(), theme: ThemeData( appBarTheme: const AppBarTheme(color: Color(0xFF13B9FF)), colorScheme: ColorScheme.fromSwatch( accentColor: const Color(0xFF13B9FF), ), ), routerDelegate: AutoRouterDelegate( _appRouter, navigatorObservers: () => [AppRouteObserver()], ), routeInformationProvider: _appRouter.routeInfoProvider(), routeInformationParser: _appRouter.defaultRouteParser(), localizationsDelegates: const [ AppLocalizations.delegate, GlobalMaterialLocalizations.delegate, ], supportedLocales: AppLocalizations.supportedLocales, debugShowCheckedModeBanner: false, home: Scaffold( bottomNavigationBar: BottomNavigationBar( currentIndex: selectedIndex, // 设置当前选中项 items: const [ BottomNavigationBarItem( icon: Icon(Icons.home_filled), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.track_changes), label: 'Activity' ), BottomNavigationBarItem( icon: Icon(Icons.person), label: 'Profile' ), ], onTap: (index) { // 更新选中索引,切换body内容 selectedIndexNotifier.state = index; }, ), // 用IndexedStack保持页面状态,切换不重建 body: IndexedStack( index: selectedIndex, children: const [ HomePage(), ActivityPage(), ProfilePage(), ], ), ), ); }
补充说明
- 如果不需要页面状态保持,把
IndexedStack换成条件判断即可:body: () { switch(selectedIndex) { case 0: return HomePage(); case 1: return ActivityPage(); case 2: return ProfilePage(); default: return HomePage(); } }(), - 若坚持用
AutoRouter实现底部导航,可以配置嵌套路由(将底部导航页面作为父路由,其他页面作为子路由),但对新手来说,切换body的方式更直接简单。
内容的提问来源于stack exchange,提问作者Coding With Jordan
相关产品推荐
相关产品推荐

