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
相关产品推荐
相关产品推荐

