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

Flutter按钮列表按钮动态变色异常问题求助

问题修复:按钮列表点击后未激活按钮无法恢复默认颜色

问题根源

你的代码核心问题是状态管理逻辑错误:

  • 父组件的activeCategory是控制按钮激活状态的唯一数据源,但子组件点击时修改的是自身内部的widget.activeCategory副本,没有触发父组件的状态更新,导致其他按钮无法感知激活状态变化,也就不会恢复默认颜色。
  • 子组件没必要做成StatefulWidget,因为它的UI完全由父组件的状态决定,不需要自身维护状态。

修复方案

1. 修改父组件(Categories)

让父组件维护激活状态,并给子组件传递点击回调,点击时更新父组件状态:

class Categories extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _Categories();
  }
}

class _Categories extends State<Categories> {
  int activeCategory = 0;
  final titles = ["Experiences", "Adventures", "Activities"];

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: titles.mapIndexed((index, title) => 
          CategoryButton(
            currentIndex: index,
            title: title,
            isActive: activeCategory == index,
            onTap: () {
              setState(() {
                activeCategory = index;
              });
            },
          )
      ).toList()
    );
  }
}

2. 修改子组件(CategoryButton)

改成StatelessWidget,仅接收父组件传递的激活状态和点击回调,不再维护自身状态:

class CategoryButton extends StatelessWidget {
  const CategoryButton({
    super.key,
    required this.currentIndex,
    required this.title,
    required this.isActive,
    required this.onTap,
  });

  final int currentIndex;
  final String title;
  final bool isActive;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    double screenWidth = MediaQuery.of(context).size.width;

    return InkWell(
      onTap: onTap,
      child: Container(
        height: 38.0,
        width: screenWidth * 0.30,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(50.0),
          color: isActive ? const Color(0xFF63D1D9) : const Color(0x00FFFFFF),
        ),
        child: Center(
          child: Text(
            title,
            style: const TextStyle(
              fontFamily: "Poppins",
              fontSize: 15.6,
              color: Color(0xFF332418),
            ),
          ),
        ),
      ),
    );
  }
}

修复说明

  • 父组件通过setState更新activeCategory时,会触发所有子按钮重新构建,每个按钮根据isActive参数判断自己是否处于激活状态,从而正确显示颜色。
  • 子组件不再修改父组件的状态,而是通过回调通知父组件处理状态变更,遵循了Flutter单向数据流的设计原则,避免了状态混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:57:17