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

Flutter中不依赖第三方包实现YouTube式底部导航栏

不依赖第三方包实现YouTube风格底部导航栏

可以通过Flutter原生的BottomAppBar + FloatingActionButton组合来实现,完全不需要第三方包,具体实现如下:

核心思路

利用BottomAppBar的shape属性设置圆形缺口,让中间的FloatingActionButton嵌入其中,再配合底部导航的图标和点击逻辑,就能还原YouTube的底部导航样式。

完整代码示例

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'YouTube Style Nav Bar',
      theme: ThemeData(primarySwatch: Colors.red),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // 当前选中的导航索引
  int _selectedIndex = 0;

  // 导航项数据(除了中间的加号)
  final List<BottomNavigationBarItem> _navItems = const [
    BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
    BottomNavigationBarItem(icon: Icon(Icons.explore), label: '探索'),
    BottomNavigationBarItem(icon: SizedBox.shrink(), label: ''), // 占位项,给中间FAB腾位置
    BottomNavigationBarItem(icon: Icon(Icons.subscriptions), label: '订阅'),
    BottomNavigationBarItem(icon: Icon(Icons.video_library), label: '库'),
  ];

  // 导航切换逻辑
  void _onItemTapped(int index) {
    // 跳过中间的占位项
    if (index == 2) return;
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('当前页面: ${_selectedIndex == 0 ? "首页" : _selectedIndex == 1 ? "探索" : _selectedIndex == 3 ? "订阅" : "库"}'),
      ),
      // 底部导航栏
      bottomNavigationBar: BottomAppBar(
        shape: const CircularNotchedRectangle(), // 圆形缺口,适配FAB
        notchMargin: 8.0, // 缺口和FAB的间距
        child: SizedBox(
          height: 60,
          child: BottomNavigationBar(
            currentIndex: _selectedIndex,
            onTap: _onItemTapped,
            type: BottomNavigationBarType.fixed,
            selectedItemColor: Theme.of(context).primaryColor,
            unselectedItemColor: Colors.grey,
            items: _navItems,
          ),
        ),
      ),
      // 中间的突出按钮
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 这里写加号按钮的点击逻辑,比如打开拍摄/上传界面
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('点击了添加按钮')),
          );
        },
        child: const Icon(Icons.add),
        backgroundColor: Theme.of(context).primaryColor,
      ),
      // 设置FAB的位置在底部导航中间
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}

关键细节说明

  • 占位项:在BottomNavigationBarItem里加一个SizedBox.shrink()的占位项,用来给中间的FAB留出位置,保证导航栏布局对称。
  • CircularNotchedRectangle:BottomAppBar的shape设置为这个,会自动生成适配FAB的圆形缺口,让视觉上更贴合。
  • floatingActionButtonLocation:设置为centerDocked,让FAB刚好卡在底部导航栏的中间缺口处,和YouTube的样式一致。
  • 样式自定义:可以根据需求调整notchMargin(缺口间距)、导航栏高度、图标颜色等,完全匹配设计需求。

内容的提问来源于stack exchange,提问作者Sanjay Tandukar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:45:51