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

如何在Flutter中设计该底部导航栏?是否有便捷实现的依赖库?

Flutter 实现带凸起中间按钮的底部导航栏

一、原生代码实现(无需依赖)

你可以通过 BottomAppBar 配合 FloatingActionButton 实现截图中的凸起效果,这种方式不需要额外依赖,完全基于Flutter原生组件:

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(
      home: const HomePage(),
      theme: ThemeData(primarySwatch: Colors.blue),
    );
  }
}

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

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

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0;

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('当前页面:${_selectedIndex + 1}'),
      ),
      bottomNavigationBar: BottomAppBar(
        shape: const CircularNotchedRectangle(), // 生成中间圆形缺口
        notchMargin: 8.0, // 缺口与凸起按钮的间距
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            IconButton(
              icon: const Icon(Icons.home),
              color: _selectedIndex == 0 ? Colors.blue : Colors.grey,
              onPressed: () => _onItemTapped(0),
            ),
            IconButton(
              icon: const Icon(Icons.search),
              color: _selectedIndex == 1 ? Colors.blue : Colors.grey,
              onPressed: () => _onItemTapped(1),
            ),
            const SizedBox(width: 40), // 为中间凸起按钮预留位置
            IconButton(
              icon: const Icon(Icons.notifications),
              color: _selectedIndex == 2 ? Colors.blue : Colors.grey,
              onPressed: () => _onItemTapped(2),
            ),
            IconButton(
              icon: const Icon(Icons.person),
              color: _selectedIndex == 3 ? Colors.blue : Colors.grey,
              onPressed: () => _onItemTapped(3),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _onItemTapped(4),
        child: const Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, // 将按钮固定在底部栏中间
    );
  }
}

二、便捷实现的依赖库

如果想要更灵活的样式和更少的自定义代码,可以使用以下成熟的第三方库:

1. curved_navigation_bar

支持自定义曲线弧度和凸起按钮样式,配置简单:

  • 添加依赖到 pubspec.yaml:
dependencies:
  curved_navigation_bar: ^1.0.3
  • 示例代码:
import 'package:curved_navigation_bar/curved_navigation_bar.dart';

// 替换Scaffold的bottomNavigationBar
bottomNavigationBar: CurvedNavigationBar(
  backgroundColor: Colors.white,
  color: Colors.blue,
  buttonBackgroundColor: Colors.blueAccent,
  items: const <Widget>[
    Icon(Icons.home, size: 30),
    Icon(Icons.search, size: 30),
    Icon(Icons.add, size: 30),
    Icon(Icons.notifications, size: 30),
    Icon(Icons.person, size: 30),
  ],
  onTap: _onItemTapped,
),

2. convex_bottom_bar

专门为凸起式底部导航设计,内置多种预设样式:

  • 添加依赖:
dependencies:
  convex_bottom_bar: ^3.2.0
  • 示例代码:
import 'package:convex_bottom_bar/convex_bottom_bar.dart';

// 替换Scaffold的bottomNavigationBar
bottomNavigationBar: ConvexAppBar(
  items: const [
    TabItem(icon: Icons.home, title: '首页'),
    TabItem(icon: Icons.search, title: '搜索'),
    TabItem(icon: Icons.add, title: '发布'),
    TabItem(icon: Icons.notifications, title: '通知'),
    TabItem(icon: Icons.person, title: '我的'),
  ],
  initialActiveIndex: _selectedIndex,
  onTap: _onItemTapped,
),

3. persistent_bottom_nav_bar

支持多种导航栏样式,包括凸起类型,还能保留页面状态,适合复杂应用:

  • 添加依赖:
dependencies:
  persistent_bottom_nav_bar: ^5.0.2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 07:15:42