如何用setState()实现ConvexBottomBar导航栏图标状态切换?
解决Convex Bottom Bar选中切换实心/轮廓图标的问题
问题描述
尝试为Convex Bottom Bar的每个选项根据选中状态切换图标样式(选中显示实心图标,未选中显示轮廓图标),但当前代码无法生效,原有代码如下:
class HomeScreen extends StatefulWidget { static const routeName = '/home'; const HomeScreen({super.key}); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { int currentIndex = 0; @override Widget build(BuildContext context) { return Scaffold( body: IndexedStack( index: currentIndex, children: screens, ), bottomNavigationBar: ConvexAppBar( backgroundColor: Theme.of(context).secondaryHeaderColor, onTap: (index) { setState() { currentIndex = index; } }, style: TabStyle.fixed, items: [ TabItem( icon: currentIndex == 0 ? Icons.local_fire_department : Icons.local_fire_department_outlined, title: 'Contests', ), TabItem( icon: currentIndex == 1 ? Icons.remove_red_eye : Icons.remove_red_eye_outlined, title: 'Reviews', ), TabItem( icon: currentIndex == 2 ? Icons.health_and_safety : Icons.health_and_safety_outlined, title: 'Add New', ), ]), ); } }
解决方案
原有代码存在两个问题:一是setState调用语法错误,二是手动判断currentIndex切换图标的逻辑与ConvexAppBar的默认图标高亮行为冲突。修改方案如下:
1. 修复setState语法错误
将setState() { ... }改为setState(() { ... }),这是Flutter中更新状态的正确语法。
2. 使用TabItem的activeIcon属性实现自动切换
ConvexAppBar的TabItem提供了activeIcon属性,专门用于指定选中状态下的图标,icon属性指定未选中状态的图标,框架会自动根据选中状态切换,无需手动判断索引。
修改后的完整代码:
class HomeScreen extends StatefulWidget { static const routeName = '/home'; const HomeScreen({super.key}); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { int currentIndex = 0; @override Widget build(BuildContext context) { return Scaffold( body: IndexedStack( index: currentIndex, children: screens, ), bottomNavigationBar: ConvexAppBar( backgroundColor: Theme.of(context).secondaryHeaderColor, onTap: (index) { // 修复setState语法 setState(() { currentIndex = index; }); }, style: TabStyle.fixed, items: [ TabItem( // 未选中时的轮廓图标 icon: Icons.local_fire_department_outlined, // 选中时的实心图标 activeIcon: Icons.local_fire_department, title: 'Contests', ), TabItem( icon: Icons.remove_red_eye_outlined, activeIcon: Icons.remove_red_eye, title: 'Reviews', ), TabItem( icon: Icons.health_and_safety_outlined, activeIcon: Icons.health_and_safety, title: 'Add New', ), ], ), ); } }
补充说明
如果坚持要手动通过currentIndex判断切换图标,需要关闭ConvexAppBar的默认图标高亮行为,可添加effect: TabEffect.none属性,但这种方式不如使用activeIcon简洁高效。
内容的提问来源于stack exchange,提问作者best_of_man
相关产品推荐
相关产品推荐

