Flutter 基于路由实现FlashyTabBar底部导航栏页面跳转
FlashyTabBar 基于命名路由的导航实现
直接按下面的逻辑改就行,完全满足你用Navigator.pushNamed体系做跳转的要求,不会出现路由栈堆积的问题。
- 首先定义tab索引和路由名的映射,避免硬编码写错:
// 路由名常量 const String routeChallenger = '/challenger'; const String routeContact = '/contact'; const String routeEvents = '/events'; const String routeQuickScan = '/quick-scan'; // 索引对应路由的映射表 const Map<int, String> tabRouteMap = { 0: routeChallenger, 1: routeContact, 2: routeEvents, 3: routeQuickScan, };
- 在State类里提前声明导航用的Key和选中索引变量:
final GlobalKey<NavigatorState> _tabNavKey = GlobalKey<NavigatorState>(); int _selectedIndex = 0;
- 补全Scaffold的逻辑,修改tab点击回调、补全body部分即可,完整代码如下:
@override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; return Scaffold( bottomNavigationBar: FlashyTabBar( animationCurve: Curves.linear, selectedIndex: _selectedIndex, showElevation: true, onItemSelected: (index) { // 点击当前已选中tab直接返回,不做重复操作 if (index == _selectedIndex) return; setState(() { _selectedIndex = index; }); // 走命名路由跳转,用替换方式避免路由栈堆叠 _tabNavKey.currentState?.pushReplacementNamed(tabRouteMap[index]!); }, items: [ FlashyTabBarItem( icon: const Icon(Icons.account_box), title: const Text('Challenger'), ), FlashyTabBarItem( icon: const Icon(Icons.phone), title: const Text('Contact'), ), FlashyTabBarItem( icon: const Icon(Icons.dashboard_rounded), title: const Text('Events'), ), FlashyTabBarItem( icon: const Icon(Icons.badge), title: const Text('Quick Scan'), ), ], ), // 补全body:用独立Navigator承载tab页路由 body: Navigator( key: _tabNavKey, initialRoute: routeChallenger, onGenerateRoute: (settings) { Widget targetPage; switch (settings.name) { case routeContact: targetPage = const ContactPage(); // 替换为你自己的联系人页组件 break; case routeEvents: targetPage = const EventsPage(); // 替换为你自己的活动页组件 break; case routeQuickScan: targetPage = const QuickScanPage(); // 替换为你自己的扫码页组件 break; case routeChallenger: default: targetPage = const ChallengerPage(); // 替换为你自己的挑战者页组件 } return MaterialPageRoute( builder: (_) => targetPage, settings: settings, ); }, ), ); }
关键说明
- body里用了独立的嵌套Navigator承载所有tab页,和App全局根路由隔离,tab内跳转子页面不会顶掉底部导航栏
- 切换tab时用
pushReplacementNamed而不是pushNamed,避免用户多次切换tab后按返回键逐层退出之前打开过的tab,符合常规APP的底部导航交互逻辑 - 独立的
_tabNavKey用来精准操作tab对应的导航栈,不会误操作全局路由 - 后续如果要在某个tab对应的页面里跳转子页面,正常调用
Navigator.pushNamed传入对应路由名即可,不需要额外处理
内容的提问来源于stack exchange,提问作者Nehal Hosalikar
相关产品推荐
相关产品推荐

