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

Flutter中如何重塑悬浮操作按钮并添加底部导航栏

Flutter底部导航栏+浮动按钮实现问题

目标样式

各位好!我是Flutter框架新手,需要大家的帮助。我想要设计一个带页面切换功能的BottomNavBar,点击标签时切换页面但底部导航栏固定在底部,同时需要实现图中所示样式的Floating Action Button。

我目前写的代码如下:

floatingActionButtonLocation : FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
  height: 64,
  width: 62,
  child: FloatingActionButton(
    onPressed: (){},
    backgroundColor: Colors.white,
    //foregroundColor: Colors.black,
    elevation: 8.0,
    shape: const const CircleBorder(),,
    child: const ImageIcon(AssetImage('Assets/Images/Rupeyo-logo-icon.png'), color: Color(0XFFDF2C25), size: 39,),
  ),
), 
bottomNavigationBar:  BottomAppBar(
  elevation: 0,
  color: Colors.white,
  child: Container(
    height: 30,
    child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        mainAxisSize: MainAxisSize.max,
        children: [
          Padding(padding: EdgeInsets.only(right: 0.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.border_all_outlined,
                  color:Colors.grey),
                Text('Category', style: TextStyle(color: Colors.grey, fontSize: 10),)
              ],
            ),
          ),
          Padding(padding: EdgeInsets.only(right: 45.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.favorite_border_outlined,
                  color:Colors.grey  ),
                Text('WishList', style: TextStyle(color: Colors.grey, fontSize: 10),)
              ],
            ),
          ),
          Padding(padding: EdgeInsets.only(right: 35.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.local_mall_outlined,
                  color:Colors.grey),
                Text('Order', style: TextStyle(color: Colors.grey, fontSize: 10),),
              ],
            ),
          ),
          Padding(padding: EdgeInsets.only(left: 0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.shopping_cart_outlined,
                  color:Colors.grey),
                Text('Cart', style: TextStyle(color: Colors.grey, fontSize: 10),)
              ],
            ),
          ), 
        ],
      ),
    ),
  ),

解决方案

1. 实现页面切换功能

用IndexedStack配合状态管理来实现页面切换,它能保留每个页面的状态,适合底部导航场景:

// 定义页面列表和当前选中索引
int _currentIndex = 0;
final List<Widget> _pages = [
  const Center(child: Text("分类页")), // 替换成你的实际页面组件
  const Center(child: Text("收藏页")),
  const Center(child: Text("订单页")),
  const Center(child: Text("购物车页")),
];

// 在Scaffold的body中使用IndexedStack
body: IndexedStack(
  index: _currentIndex,
  children: _pages,
),

2. 底部导航栏点击切换逻辑

给每个导航项添加点击事件,更新选中索引并同步图标文字颜色:

// 以分类项为例,其他项同理修改索引和判断条件
InkWell(
  onTap: () {
    setState(() {
      _currentIndex = 0;
    });
  },
  child: Column(
    mainAxisSize: MainAxisSize.min,
    children: [
      Icon(Icons.border_all_outlined,
        color: _currentIndex == 0 ? const Color(0XFFDF2C25) : Colors.grey),
      Text('Category', style: TextStyle(color: _currentIndex == 0 ? const Color(0XFFDF2C25) : Colors.grey, fontSize: 10),)
    ],
  ),
),

3. 浮动按钮样式修正与功能补充

  • 修复代码错误:去掉重复的const,将shape: const const CircleBorder(),改为shape: const CircleBorder(),
  • 给中间按钮添加点击逻辑(比如跳转到对应页面)
  • 可去掉外层Container,直接设置FAB的大小:
floatingActionButton: FloatingActionButton(
  onPressed: (){
    setState(() {
      _currentIndex = 2; // 按需设置对应页面索引
    });
  },
  backgroundColor: Colors.white,
  elevation: 8.0,
  shape: const CircleBorder(),
  child: const ImageIcon(AssetImage('Assets/Images/Rupeyo-logo-icon.png'), color: Color(0XFFDF2C25), size: 39,),
),

4. 底部导航栏布局优化

  • 调整底部栏高度(原30太矮,建议设为50)
  • 用Expanded和SizedBox替代固定padding,让布局更规整:
bottomNavigationBar: BottomAppBar(
  elevation: 0,
  color: Colors.white,
  child: Container(
    height: 50,
    padding: const EdgeInsets.symmetric(vertical: 4),
    child: Row(
      children: [
        Expanded(child: /* 分类项 */),
        Expanded(child: /* 收藏项 */),
        const SizedBox(width: 60), // 中间留出FAB位置
        Expanded(child: /* 订单项 */),
        Expanded(child: /* 购物车项 */),
      ],
    ),
  ),
),

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 07:07:07