Flutter中使用Navigator.push跳转后如何保留底部导航栏?
解决方案:保持底部导航栏可见的页面跳转
要实现跳转新页面时仍显示底部导航栏,核心思路是给每个底部导航标签配置独立的嵌套导航器,这样每个标签页拥有自己的路由栈,跳转时不会覆盖外层的Scaffold(包含底部导航栏)。
步骤1:修改main.dart代码
调整你的MyAppState类,添加嵌套导航器并更新底部导航的点击逻辑:
class MyAppState extends State<MyApp> { int _selectedIndex = 0; // 为每个标签页创建导航器全局键,用于控制路由 final GlobalKey<NavigatorState> _homeNavigatorKey = GlobalKey(); final GlobalKey<NavigatorState> _addNavigatorKey = GlobalKey(); final GlobalKey<NavigatorState> _notificationsNavigatorKey = GlobalKey(); final GlobalKey<NavigatorState> _profileNavigatorKey = GlobalKey(); // 获取当前选中标签的导航器键 GlobalKey<NavigatorState> get _currentNavigatorKey { switch (_selectedIndex) { case 0: return _homeNavigatorKey; case 1: return _addNavigatorKey; case 2: return _notificationsNavigatorKey; case 3: return _profileNavigatorKey; default: return _homeNavigatorKey; } } void onTapImplemented(int index) { if (index == _selectedIndex) { // 重复点击当前标签时,返回该标签的根页面 _currentNavigatorKey.currentState?.popUntil((route) => route.isFirst); } else { setState(() { _selectedIndex = index; }); } } // 每个标签页对应一个嵌套导航器 final List<Widget> _widgetOptions = <Widget>[ Navigator( key: _homeNavigatorKey, initialRoute: '/', onGenerateRoute: (settings) { return MaterialPageRoute( builder: (context) => const HomePage(), ); }, ), Navigator( key: _addNavigatorKey, initialRoute: '/', onGenerateRoute: (settings) { return MaterialPageRoute( builder: (context) => const AddActivity(), ); }, ), Navigator( key: _notificationsNavigatorKey, initialRoute: '/', onGenerateRoute: (settings) { return MaterialPageRoute( builder: (context) => const Notifications(), ); }, ), Navigator( key: _profileNavigatorKey, initialRoute: '/', onGenerateRoute: (settings) { return MaterialPageRoute( builder: (context) => const ProfilePage(), ); }, ), ]; @override Widget build(BuildContext context) { return MaterialApp( title: 'Social Event App', theme: ThemeData( colorScheme: ColorScheme.fromSeed( seedColor: const Color.fromARGB(255, 0, 0, 0), primary: Colors.black, secondary: Colors.white, ), useMaterial3: true, ), home: Scaffold( body: _widgetOptions.elementAt(_selectedIndex), bottomNavigationBar: BottomNavigationBar( items: const <BottomNavigationBarItem>[ BottomNavigationBarItem( icon: Icon(Icons.home), label: '', ), BottomNavigationBarItem( icon: Icon(Icons.add_outlined), label: '', ), BottomNavigationBarItem( icon: Icon(Icons.notifications), label: '', ), BottomNavigationBarItem( icon: Icon(Icons.person), label: '', ), ], selectedItemColor: const Color.fromARGB(255, 0, 0, 0), unselectedItemColor: const Color.fromARGB(255, 146, 138, 138), selectedFontSize: 0, currentIndex: _selectedIndex, backgroundColor: const Color.fromARGB(255, 255, 255, 255), onTap: onTapImplemented, ), ), ); } }
步骤2:修改页面跳转代码
在需要跳转的页面(比如ProfilePage)中,使用常规的Navigator.push即可,此时路由会被推送到当前标签的嵌套导航器中,底部导航栏保持可见:
ElevatedButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const EditProfilePage(), // 替换为你的目标页面 ), ); }, child: const Text('Edit Profile'), )
关键说明
- 嵌套导航器:每个标签页的内容被包裹在独立的
Navigator中,确保路由栈独立,不会影响外层Scaffold。 - 重复点击标签:添加了返回根页面的逻辑,提升用户体验。
- 避免RouteSettings错误:通过
onGenerateRoute直接指定初始页面,无需配置全局命名路由,规避了你遇到的路由名称相关问题。
内容的提问来源于stack exchange,提问作者Coldmalt
相关产品推荐
相关产品推荐

