You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:51:17