GetX调用Get.toNamed跳转新页面时底部导航栏仍显示如何解决
问题根源
出现这个问题核心是两个写法问题:
- 入口使用了原生
MaterialApp而非GetX要求的GetMaterialApp,Get的路由栈没有接管全局导航,新页面直接压在你硬编码的根布局(带底部导航的Scaffold)上层,不会触发根布局的组件刷新。 - 底部导航栏是硬编码在根Scaffold中的固定组件,默认所有压栈跳转的新页面都会盖在它上层,不会自动隐藏。
- 额外提一句,你现有代码里通知 tab 的label写错成了"Home",记得顺手修正。
修复步骤
1. 替换入口组件,注册全局路由
把main.dart中的MaterialApp替换为GetMaterialApp,统一注册所有页面路由,不要把底部导航组件直接硬塞在初始Scaffold的body里。修改后的main.dart代码如下:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); await GetStorage.init(); runApp(MyApp()); } class MyApp extends StatelessWidget { final authC = Get.put(AuthController(), permanent: true); @override Widget build(BuildContext context) { return FutureBuilder( future: Future.delayed(const Duration(seconds: 3)), builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return FutureBuilder( future: authC.firstInitialized(), builder: (context, snapshot) => const SplashScreen(), ); } // 替换为GetMaterialApp接管路由 return GetMaterialApp( initialRoute: '/', // 注册全量路由 getPages: [ GetPage(name: '/', page: () => const BottomNavigationsBar()), GetPage(name: Routes.UPLOAD_PRODUCT, page: () => const UploadProductPage()), // 其余独立页面路由在此处继续添加 ], ); }, ); } }
2. 给底部导航增加路由判断逻辑
修改底部导航组件,根据当前路由地址判断是否显示底部栏:只有处于底部导航挂载的主页体系下才显示栏,跳转到独立页面时自动隐藏。修改后的BottomNavigationsBar代码如下:
class BottomNavigationsBar extends StatefulWidget { const BottomNavigationsBar({Key? key}) : super(key: key); @override State<BottomNavigationsBar> createState() => _BottomNavigationsBarState(); } class _BottomNavigationsBarState extends State<BottomNavigationsBar> { int currentIndex = 0; final List _pages = [ EcoHomePageView(), ChatCheckLogin(), EcoNotificationPageView(), UserCheckLogin(), ]; // 如需多个tab对应独立路由,可把需要显示底部栏的路由都加到这个列表 final List<String> _showBottomNavRoutes = ['/']; @override Widget build(BuildContext context) { return Scaffold( body: _pages[currentIndex], // 当前路由在显示列表中才渲染底部栏,否则返回null隐藏 bottomNavigationBar: _showBottomNavRoutes.contains(Get.currentRoute) ? BottomNavigationBar( unselectedItemColor: Colors.grey.shade700, selectedItemColor: Colors.red, showSelectedLabels: true, showUnselectedLabels: true, type: BottomNavigationBarType.fixed, onTap: ontap, currentIndex: currentIndex, items: const [ BottomNavigationBarItem( icon: Icon(Icons.home_outlined), label: "Home", activeIcon: Icon(Icons.home)), BottomNavigationBarItem( icon: Icon(Icons.message_outlined), label: "Chat", activeIcon: Icon(Icons.message)), BottomNavigationBarItem( icon: Icon(Icons.notifications_outlined), label: "Notification", activeIcon: Icon(Icons.notifications)), BottomNavigationBarItem( icon: Icon(Icons.person_outline), label: "User", activeIcon: Icon(Icons.person)), ], ) : null, ); } void ontap(int index) { setState(() { currentIndex = index; }); } }
注意事项
- 底部导航挂载的4个内部页面,继续用现有
currentIndex切换的逻辑即可,不要用Get.to做跳转,否则会触发路由判断隐藏底部栏。 - 后续新增不需要显示底部栏的独立页面,只要在
getPages里注册路由即可,不需要额外修改导航栏逻辑,跳转到这些页面时底部栏会自动隐藏,返回主页时自动恢复。 - 如果后续要把底部导航的四个tab拆成独立路由,只要把对应路由地址加到
_showBottomNavRoutes列表里,就能保持底部栏常显。
内容的提问来源于stack exchange,提问作者Stanly
相关产品推荐
相关产品推荐

