Flutter如何给底部导航栏项添加间距 使其远离居中悬浮操作按钮
问题描述
我现在实现了一个带有悬浮操作按钮的底部导航栏,效果如下图所示:
由于导航栏中间设置了悬浮操作按钮,我希望首页(home)和个人中心(profile)图标能够与按钮保持更远的距离。我尝试给图标添加内边距,但显然图标对应的文字标签不会跟随图标一起移动。请问该如何实现这个需求?为了更清晰说明需求,下方是我想要实现的底部导航栏效果图:
以下是我的代码:
class MainNavigationPage extends StatelessWidget { @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () { //TODO implement later }, child: Consumer<MainNavigationNotifier>( builder: (_, notifier, __) => Scaffold( body: IndexedStack(index: notifier.tabIndex, children: [ IndexedStack( index: notifier.pages[0].length - 1, children: notifier.pages[0], ), IndexedStack( index: notifier.pages[1].length - 1, children: notifier.pages[1], ), ]), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, floatingActionButton: Align( alignment: Alignment.bottomCenter, child: Container( padding: const EdgeInsets.only(bottom: 6.0), child: FloatingActionButton( onPressed: () {}, child: SvgPicture.asset(AppVectors.CREATE_ORDER), ), ), ), bottomNavigationBar: Container( decoration: BoxDecoration( boxShadow: <BoxShadow>[ BoxShadow( color: AppColors.LIGHT_GREY.withOpacity(0.4), blurRadius: 4, ), ], ), child: BottomNavigationBar( type: BottomNavigationBarType.fixed, onTap: notifier.onTabTap(), elevation: 10, currentIndex: notifier.tabIndex, backgroundColor: Theme.of(context).bottomAppBarColor, selectedItemColor: Theme.of(context).primaryColor, unselectedItemColor: Theme.of(context).unselectedWidgetColor, unselectedFontSize: 14, items: [ BottomNavigationBarItem( icon: Padding( padding: const EdgeInsets.only(bottom: 4.0), child: SvgPicture.asset( AppVectors.HOME, height: 25, color: Theme.of(context).unselectedWidgetColor, ), ), label: AppStrings.HOME, tooltip: "", activeIcon: Padding( padding: const EdgeInsets.only(bottom: 4.0), child: SvgPicture.asset( AppVectors.HOME, height: 25, color: Theme.of(context).primaryColor, ), ), ), BottomNavigationBarItem( activeIcon: Padding( padding: const EdgeInsets.all(4.0), child: SvgPicture.asset( AppVectors.PROFILE, height: 27, width: 27, color: Theme.of(context).primaryColor, ), ), tooltip: "", icon: Padding( padding: const EdgeInsets.all(4.0), child: SvgPicture.asset( AppVectors.PROFILE, height: 27, width: 27, color: Theme.of(context).unselectedWidgetColor, // color: Theme.of(context).focusColor, ), ), label: AppStrings.PROFILE), ], ), ), ), ), ); } }
解决方案
单独给BottomNavigationBarItem的icon属性加padding不生效,是因为系统的底部导航栏组件会单独布局图标和文字标签,图标区域的padding不会影响标签的布局位置。可以通过以下两种方式实现需求:
方案1:新增占位导航项(改动最小)
在两个现有导航项中间插入一个空的占位BottomNavigationBarItem,系统会自动分配布局空间,让左右两个导航项向两侧偏移,同时还可以给左右图标额外加对称的边距调整距离,最终效果和需求一致。
需要同步修改索引映射逻辑,避免点击中间占位项触发错误的切换:
// 仅展示修改后的BottomNavigationBar部分代码 BottomNavigationBar( type: BottomNavigationBarType.fixed, // 处理点击事件,跳过中间占位项,做索引映射 onTap: (index) { if (index != 1) { final targetIndex = index == 2 ? 1 : index; notifier.onTabTap()(targetIndex); } }, elevation: 10, // 同步修改当前选中索引的映射 currentIndex: notifier.tabIndex == 1 ? 2 : notifier.tabIndex, backgroundColor: Theme.of(context).bottomAppBarColor, selectedItemColor: Theme.of(context).primaryColor, unselectedItemColor: Theme.of(context).unselectedWidgetColor, unselectedFontSize: 14, items: [ BottomNavigationBarItem( icon: Padding( padding: const EdgeInsets.only(bottom: 4.0, right: 30), // 右侧加边距远离中间按钮 child: SvgPicture.asset( AppVectors.HOME, height: 25, color: Theme.of(context).unselectedWidgetColor, ), ), label: AppStrings.HOME, tooltip: "", activeIcon: Padding( padding: const EdgeInsets.only(bottom: 4.0, right: 30), child: SvgPicture.asset( AppVectors.HOME, height: 25, color: Theme.of(context).primaryColor, ), ), ), // 中间占位项,不显示任何内容 const BottomNavigationBarItem(icon: SizedBox.shrink(), label: ''), BottomNavigationBarItem( activeIcon: Padding( padding: const EdgeInsets.all(4.0).copyWith(left: 30), // 左侧加边距远离中间按钮 child: SvgPicture.asset( AppVectors.PROFILE, height: 27, width: 27, color: Theme.of(context).primaryColor, ), ), tooltip: "", icon: Padding( padding: const EdgeInsets.all(4.0).copyWith(left: 30), child: SvgPicture.asset( AppVectors.PROFILE, height: 27, width: 27, color: Theme.of(context).unselectedWidgetColor, ), ), label: AppStrings.PROFILE), ], )
方案2:自定义底部导航栏
如果后续还有更多样式调整需求,可以放弃系统的BottomNavigationBar组件,自己用Row、GestureDetector等组件自定义底部导航栏布局,完全控制每个元素的位置和间距,灵活性更高。
内容的提问来源于stack exchange,提问作者Kimiya Zargari
相关产品推荐
相关产品推荐

