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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:47:46