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

