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

Flutter原生BottomNavigationBar如何为选中项添加顶部指示线

解决方案

原生BottomNavigationBar没有内置顶部指示线的属性,我们可以用Stack组件将指示线和底部导航栏叠加,通过动态计算指示线的位置来实现需求。

修改后的完整代码如下:

class DashboardScreen extends StatefulWidget {
  const DashboardScreen({Key? key}) : super(key: key);

  @override
  State<DashboardScreen> createState() => _DashboardScreenState();
}

class _DashboardScreenState extends State<DashboardScreen> {
  int _selectedIndex = 0;
  final int _totalItems = 4; // 底部导航项总数
  final double _indicatorWidth = 40; // 指示线宽度

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final itemWidth = screenWidth / _totalItems;
    // 计算指示线左侧偏移量,确保线条居中在选中项上方
    final indicatorLeft = itemWidth * _selectedIndex + (itemWidth - _indicatorWidth) / 2;

    return Scaffold(
      bottomNavigationBar: Stack(
        children: [
          // 原底部导航栏
          Theme(
            data: Theme.of(context).copyWith(
              canvasColor: const Color(0xFF161E21), // 背景色
            ),
            child: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              showUnselectedLabels: true,
              unselectedFontSize: 14,
              selectedItemColor: const Color(0xFF00A8A8), // 选中项颜色
              unselectedItemColor: Colors.white, // 未选中项颜色
              currentIndex: _selectedIndex,
              onTap: (index) {
                setState(() {
                  _selectedIndex = index;
                });
              },
              items: [
                BottomNavigationBarItem(
                  icon: _selectedIndex == 0 
                      ? SvgPicture.asset('assets/icons/selectedHome.svg') 
                      : SvgPicture.asset('assets/icons/home.svg'),
                  label: 'الرئيسية',
                ),
                BottomNavigationBarItem(
                  icon: _selectedIndex == 1 
                      ? SvgPicture.asset('assets/icons/selectedTools.svg') 
                      : SvgPicture.asset('assets/icons/tools.svg'),
                  label: 'الصيانة',
                ),
                BottomNavigationBarItem(
                  icon: _selectedIndex == 2 
                      ? SvgPicture.asset('assets/icons/selectedCharge.svg') 
                      : SvgPicture.asset('assets/icons/charge.svg'),
                  label: 'الشحن',
                ),
                BottomNavigationBarItem(
                  icon: _selectedIndex == 3 
                      ? SvgPicture.asset('assets/icons/selectedCar.svg') 
                      : SvgPicture.asset('assets/icons/car.svg'),
                  label: 'المركبات',
                ),
              ],
            ),
          ),
          // 顶部指示线
          Positioned(
            top: 0,
            left: indicatorLeft,
            width: _indicatorWidth,
            height: 2, // 指示线高度
            child: Container(
              color: const Color(0xFF00A8A8), // 指示线颜色与选中项保持一致
            ),
          ),
        ],
      ),
    );
  }
}

关键说明

  • 用Stack将指示线层叠在导航栏上方,完全保留原有导航交互逻辑
  • 通过屏幕宽度和导航项总数计算每个项的宽度,保证指示线始终居中对齐选中项
  • 可通过调整_indicatorWidth、指示线height参数自定义样式
  • 切换选中项时,setState会自动重新计算位置,实现跟随动画

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:17:18