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

Flutter中如何搭配底部导航栏实现正确的路由导航功能

Flutter iOS风格底部导航搭配路由导航实现方案

核心实现思路

iOS风格的底部导航推荐使用Flutter官方内置的Cupertino系列组件实现,该套组件完全遵循iOS设计规范,自带独立路由栈管理能力,无需依赖PageView手动处理页面逻辑。

基础实现步骤

1. 核心组件组合

  • 使用CupertinoTabScaffold作为根容器,统一管理底部tab栏和对应tab的页面路由
  • 使用CupertinoTabBar作为底部导航栏,默认自带iOS原生的毛玻璃效果、选中动效
  • 每个tab对应一个CupertinoTabView组件,内部自带独立的Navigator实例,支持单tab内的页面push/pop操作,切换tab时不会丢失当前tab的浏览状态

2. 完整代码示例

import 'package:flutter/cupertino.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      theme: const CupertinoThemeData(
        primaryColor: CupertinoColors.systemBlue,
      ),
      home: const MainTabPage(),
      // 可配置全局命名路由
      routes: {
        '/globalDetail': (context) => const GlobalDetailPage(),
      },
    );
  }
}

class MainTabPage extends StatelessWidget {
  const MainTabPage({super.key});

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.home),
            label: "首页",
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.list_bullet),
            label: "列表",
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.person),
            label: "我的",
          ),
        ],
      ),
      tabBuilder: (BuildContext context, int index) {
        switch (index) {
          case 0:
            return CupertinoTabView(
              builder: (context) => const HomePage(),
              // 首页tab私有路由
              routes: {
                '/homeDetail': (context) => const HomeDetailPage(),
              },
            );
          case 1:
            return CupertinoTabView(
              builder: (context) => const ListPage(),
            );
          case 2:
            return CupertinoTabView(
              builder: (context) => const ProfilePage(),
            );
          default:
            return const SizedBox.shrink();
        }
      },
    );
  }
}

// 首页实现
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text("首页"),
      ),
      child: Center(
        child: CupertinoButton.filled(
          onPressed: () {
            // 跳转当前tab私有路由
            Navigator.pushNamed(context, '/homeDetail');
          },
          child: const Text("打开首页详情"),
        ),
      ),
    );
  }
}

// 首页详情页
class HomeDetailPage extends StatelessWidget {
  const HomeDetailPage({super.key});

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text("首页详情"),
      ),
      child: Center(
        child: CupertinoButton.filled(
          onPressed: () {
            // 跳转全局路由
            Navigator.pushNamed(context, '/globalDetail');
          },
          child: const Text("打开全局公共详情"),
        ),
      ),
    );
  }
}

// 全局公共详情页
class GlobalDetailPage extends StatelessWidget {
  const GlobalDetailPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text("全局详情"),
      ),
      child: Center(child: Text("全局公共详情页")),
    );
  }
}

// 其余占位页面
class ListPage extends StatelessWidget {
  const ListPage({super.key});
  @override
  Widget build(BuildContext context) => const CupertinoPageScaffold(
    navigationBar: CupertinoNavigationBar(middle: Text("列表")),
    child: Center(child: Text("列表页")),
  );
}

class ProfilePage extends StatelessWidget {
  const ProfilePage({super.key});
  @override
  Widget build(BuildContext context) => const CupertinoPageScaffold(
    navigationBar: CupertinoNavigationBar(middle: Text("我的")),
    child: Center(child: Text("我的页")),
  );
}

关键特性说明

  • 独立路由栈:每个tab的页面操作互不影响,切换tab后返回时会保留之前的页面浏览记录,和原生iOS应用行为完全一致
  • 原生动效:默认自带iOS风格的页面水平转场动画、右滑返回手势,无需额外自定义配置
  • 自动保活:无需手动混入AutomaticKeepAliveClientMixin,tab页面默认会保持状态,切换tab不会触发页面重建

扩展适配方案

  • 多平台适配:如果需要同时兼容安卓和iOS,可通过Theme.of(context).platform判断运行平台,安卓端使用Scaffold + BottomNavigationBar + IndexedStack组合实现,iOS端使用上述Cupertino组件方案即可
  • 自定义底部栏:可直接修改CupertinoTabBar的样式属性,也可替换为自定义的底部栏组件,只需同步更新CupertinoTabScaffold的tabBar参数
  • 路由拦截:可通过CupertinoApp的onGenerateRoute、onUnknownRoute参数统一处理全局路由拦截、404页面等逻辑

内容的提问来源于stack exchange,提问作者Dipak Ramoliya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:15:03