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

Flutter:如何在导航栏上方添加定位图标(persistent_bottom_nav_bar)

解决方案

要实现中间图标悬浮在导航栏上方的效果,核心问题是当前固定高度的SizedBox会截断向上偏移的图标。通过Stack分层布局配合Positioned即可解决,具体修改如下:

class MyCustomNavigationBar extends StatelessWidget {
  final List<PersistentBottomNavBarItem> items;
  final int selectedIndex;
  final ValueChanged<int> onItemSelected;

  const MyCustomNavigationBar({
    required this.items,
    required this.selectedIndex,
    required this.onItemSelected,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 外层容器增加高度,给悬浮图标预留显示空间
    return SizedBox(
      width: double.infinity,
      height: 80.0,
      child: Stack(
        alignment: Alignment.bottomCenter,
        children: [
          // 底层:常规导航栏区域(高度保持原60)
          SizedBox(
            height: 60.0,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: items.map((item) {
                int index = items.indexOf(item);
                // 跳过中间图标,用占位容器保持布局对称
                if (index == 2) return const SizedBox(width: 60);

                Widget icon = IconTheme(
                  data: IconThemeData(
                    size: item.iconSize,
                    color: selectedIndex == index 
                        ? item.activeColorPrimary 
                        : item.inactiveColorPrimary,
                  ),
                  child: item.icon,
                );

                return GestureDetector(
                  onTap: () => onItemSelected(index),
                  child: icon,
                );
              }).toList(),
            ),
          ),
          // 上层:悬浮的中间图标
          Positioned(
            bottom: 20.0, // 向上偏移,悬浮在导航栏上方
            child: GestureDetector(
              onTap: () => onItemSelected(2),
              child: DecoratedBox(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(30),
                  color: Colors.blue,
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black12,
                      blurRadius: 4,
                      offset: const Offset(0, 2),
                    )
                  ],
                ),
                child: Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: IconTheme(
                    data: IconThemeData(
                      size: items[2].iconSize,
                      color: items[2].activeColorPrimary,
                    ),
                    child: items[2].icon,
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

关键调整说明:

  • 用Stack实现分层:底层是常规导航栏,上层单独放置悬浮图标,避免图标被容器截断
  • 给中间图标通过Positioned设置偏移量,让它悬浮在导航栏上方
  • 原导航栏的Row中给中间位置留空,保证左右图标布局对称
  • 给悬浮图标添加点击事件,确保页面切换逻辑正常触发
  • 外层容器高度调整为80,为悬浮图标预留足够显示空间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:17:39