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

Flutter:InkWell按钮组点击切换时前一个按钮无法恢复原色的问题解决方案

这个问题的核心是每个NavigationButton都在自己的状态类里独立维护颜色状态,它们之间没有任何通信,所以点击新按钮时,旧按钮根本不知道要把颜色改回去。解决办法是把选中状态提升到父组件,让父组件统一管理哪个按钮被选中,这样所有按钮都能根据父组件的状态来更新自己的颜色。

下面是具体的修改步骤和代码:

1. 重构NavigationButton,让它依赖父组件传递的状态

把NavigationButton改成无状态组件,不再自己维护颜色,而是接收父组件传来的isSelected(是否被选中)和点击回调onTap:

class NavigationButton extends StatelessWidget {
  const NavigationButton({
    Key? key,
    required this.title,
    required this.isSelected,
    required this.onTap,
  }) : super(key: key);

  final String title;
  final bool isSelected;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        InkWell(
          highlightColor: Colors.transparent,
          splashColor: Colors.transparent,
          child: Text(
            title,
            style: const TextStyle(color: Colors.white, fontSize: 25),
          ),
          onTap: onTap,
        ),
        const SizedBox(width: 10),
        Container(
          width: 10,
          height: 10,
          decoration: BoxDecoration(
            // 根据isSelected切换颜色
            color: isSelected ? Colors.red : Colors.white,
            shape: BoxShape.circle,
          ),
        ),
      ],
    );
  }
}

2. 在父组件中维护选中状态,并传递给每个按钮

在包含导航菜单的父组件的状态类里,添加一个变量记录当前选中的按钮索引,然后在构建NavigationButton时,把是否选中的判断和点击回调传进去:

// 父组件的状态类示例
class _ParentWidgetState extends State<ParentWidget> {
  // 初始值设为-1,表示没有按钮被选中
  int _selectedIndex = -1;
  // 假设_sectionsName是你的菜单标题列表
  final List<String> _sectionsName = ['菜单1', '菜单2', '菜单3'];

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 205,
      width: 210,
      padding: const EdgeInsets.only(right: 10),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          for (int index = 0; index < _sectionsName.length; index++)
            NavigationButton(
              title: _sectionsName[index],
              // 判断当前按钮是否是选中的那个
              isSelected: index == _selectedIndex,
              // 点击时更新选中索引
              onTap: () {
                setState(() {
                  _selectedIndex = index;
                });
              },
            )
        ],
      ),
    );
  }
}

为什么这样能解决问题?

  • 父组件统一管理_selectedIndex,所有按钮的选中状态都依赖这个变量,实现了状态共享。
  • 当点击某个按钮时,父组件更新_selectedIndex并调用setState,所有按钮都会重新构建,根据新的索引判断自己是否应该显示红色,之前选中的按钮会因为index != _selectedIndex自动变回白色。

这样就实现了点击一个按钮变红,其他按钮变回白色的单选效果啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:43:10