Flutter如何实现点击navbar导航项时修改对应项颜色
Flutter 底部导航点击后切换图标颜色实现方案
你当前的代码无法实现点击变色,核心问题有三个:
- 所有图标的
color属性硬编码为固定值textGrey,没有和选中状态变量绑定 - 每个导航按钮的点击回调中,没有调用你预先写好的
_onItemTapped方法更新选中索引 - 直接使用
Get.to跳转页面会覆盖当前的底部导航栏,无法实现导航常驻效果,不符合常规底部导航交互逻辑。
具体修改方式
- 删除未被使用的冗余变量
_selectedTab - 每个导航按钮的点击事件中,先调用
_onItemTapped传入当前项对应的索引值,触发状态更新 - 将每个
Icon的color属性改为状态判断逻辑:当前项索引等于_selectedIndex时显示选中色(可自定义为主题色/品牌色),否则显示默认灰色textGrey - 推荐使用
IndexedStack管理导航对应的子页面,不需要每次点击都做路由跳转,保证底部导航栏常驻,同时保留各页面的状态。
修改后的可运行代码如下:
class BottomNavigation extends StatefulWidget { const BottomNavigation({Key? key}) : super(key: key); @override State<BottomNavigation> createState() => _BottomNavigationState(); } class _BottomNavigationState extends State<BottomNavigation> { int _selectedIndex = 0; // 导航项对应的页面列表 final List<Widget> _navPages = [ const HomeScreenCompanyList(), const CompanyList(), const Category(), const Services(), const Center(child: Text("个人中心")), // 替换为你的个人页组件 ]; void _onItemTapped(int index) { setState(() { _selectedIndex = index; }); } @override Widget build(BuildContext context) { return Scaffold( // 用IndexedStack承载页面,切换时不销毁页面状态 body: IndexedStack( index: _selectedIndex, children: _navPages, ), bottomNavigationBar: Container( decoration: const BoxDecoration( color: backgroundWhite, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ IconButton( enableFeedback: false, onPressed: () => _onItemTapped(0), icon: Icon( Icons.home_outlined, // 选中时显示主题色,未选中显示灰色 color: _selectedIndex == 0 ? Theme.of(context).primaryColor : textGrey, size: 25, ), ), IconButton( enableFeedback: false, onPressed: () => _onItemTapped(1), icon: Icon( Icons.folder_outlined, color: _selectedIndex == 1 ? Theme.of(context).primaryColor : textGrey, size: 25, ), ), IconButton( enableFeedback: false, onPressed: () => _onItemTapped(2), icon: Icon( Icons.search, color: _selectedIndex == 2 ? Theme.of(context).primaryColor : textGrey, size: 25, ), ), IconButton( enableFeedback: false, onPressed: () => _onItemTapped(3), icon: Icon( Icons.edit_note_outlined, color: _selectedIndex == 3 ? Theme.of(context).primaryColor : textGrey, size: 25, ), ), IconButton( enableFeedback: false, onPressed: () => _onItemTapped(4), icon: Icon( Icons.person_outline, color: _selectedIndex == 4 ? Theme.of(context).primaryColor : textGrey, size: 25, ), ), ], ), ), ); } }
补充说明
- 如果你确实需要在点击导航时用Get跳转路由,只需要在
_onItemTapped方法中补充对应路由跳转逻辑即可,图标颜色判断逻辑不需要改动 - 选中色可以根据需求自行替换,不需要强制使用主题色
- 如果需要选中时同时切换图标为填充样式,可以和颜色逻辑一样,根据
_selectedIndex判断传入不同的IconData即可
内容的提问来源于stack exchange,提问作者nayo
相关产品推荐
相关产品推荐

