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

Flutter实现按钮选中/取消选中效果 求代码修正

实现按钮选中/取消选中效果的Flutter代码修正

按钮选中/取消选中效果

我希望实现如图所示的按钮选中与取消选中效果,以下是我的代码:

原按钮组件代码

Widget buttonRow(String dateTime, bool verticalLine, int buttonNumber) {
  return InkWell(
    onTap: (){
      print('select-deSelect');
    },
    child: Container(
      height: 50,
      child: Column(
         mainAxisAlignment: MainAxisAlignment.spaceEvenly,
       // crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          buttonNumber == 1 ? SizedBox(height: 10): SizedBox(height: 0),
          Text(
            dateTime,
            textAlign: TextAlign.center,
            maxLines: 2,
            style: TextStyle(
              color: Color(0xFFCC306F),
              fontSize: 13,
              fontFamily: 'PingFang SC',
              fontWeight: FontWeight.w400,
              height: 1.38,
              letterSpacing: -0.09,
            ),
          ),
          buttonNumber == 1? SizedBox(height: 15): SizedBox(height: 10),
          Container(
            width: 63,
            height: 3,
            decoration: BoxDecoration(color: Color(0xFFF2C547)),
          )
        ],
      ),
    )
  );
}

原调用代码

Row(
          children: [
            Expanded(flex: 1,child: buttonRow('直播中', true, 1)),
            Container(color: Colors.black45, height: 50, width: 2,),
            Expanded(flex: 1,child: buttonRow("今天\n11月24日", true,2)),
            Container(color: Colors.black45, height: 50, width: 2,),
            Expanded(flex: 1,child: buttonRow("星期一\n11月25日", true, 3)),
            Container(color: Colors.black45, height: 50, width: 2,),
            Expanded(flex: 1,child: buttonRow("星期二\n11月26日", true, 4)),
          ],
        ),

修正后的代码实现

1. 修改按钮组件,支持状态控制

Widget buttonRow(
  String dateTime,
  bool verticalLine,
  int buttonIndex, {
  required bool isSelected,
  required VoidCallback onTap,
}) {
  return InkWell(
    onTap: onTap,
    child: Container(
      height: 50,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          buttonIndex == 0 ? SizedBox(height: 10) : SizedBox(height: 0),
          Text(
            dateTime,
            textAlign: TextAlign.center,
            maxLines: 2,
            style: TextStyle(
              color: isSelected ? Color(0xFFCC306F) : Colors.grey.shade600,
              fontSize: 13,
              fontFamily: 'PingFang SC',
              fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
              height: 1.38,
              letterSpacing: -0.09,
            ),
          ),
          buttonIndex == 0 ? SizedBox(height: 15) : SizedBox(height: 10),
          isSelected
              ? Container(
                  width: 63,
                  height: 3,
                  decoration: BoxDecoration(color: Color(0xFFF2C547)),
                )
              : SizedBox.shrink(),
        ],
      ),
    ),
  );
}

2. 父组件维护选中状态并调用按钮

// 父组件需为StatefulWidget,示例如下:
class YourParentWidget extends StatefulWidget {
  const YourParentWidget({super.key});

  @override
  State<YourParentWidget> createState() => _YourParentWidgetState();
}

class _YourParentWidgetState extends State<YourParentWidget> {
  // 默认选中第一个按钮(索引0)
  int _selectedButtonIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          flex: 1,
          child: buttonRow(
            '直播中',
            true,
            0,
            isSelected: _selectedButtonIndex == 0,
            onTap: () => setState(() => _selectedButtonIndex = 0),
          ),
        ),
        Container(color: Colors.black45, height: 50, width: 2),
        Expanded(
          flex: 1,
          child: buttonRow(
            "今天\n11月24日",
            true,
            1,
            isSelected: _selectedButtonIndex == 1,
            onTap: () => setState(() => _selectedButtonIndex = 1),
          ),
        ),
        Container(color: Colors.black45, height: 50, width: 2),
        Expanded(
          flex: 1,
          child: buttonRow(
            "星期一\n11月25日",
            true,
            2,
            isSelected: _selectedButtonIndex == 2,
            onTap: () => setState(() => _selectedButtonIndex = 2),
          ),
        ),
        Container(color: Colors.black45, height: 50, width: 2),
        Expanded(
          flex: 1,
          child: buttonRow(
            "星期二\n11月26日",
            true,
            3,
            isSelected: _selectedButtonIndex == 3,
            onTap: () => setState(() => _selectedButtonIndex = 3),
          ),
        ),
      ],
    );
  }
}

核心修改说明

  • 给按钮组件新增isSelected参数,用于控制文本颜色、字重和底部横线的显示状态
  • 新增onTap回调,让父组件处理选中状态的更新
  • 父组件通过_selectedButtonIndex维护当前选中项,点击按钮时调用setState更新状态,触发UI重绘

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:27:11