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

Flutter中ListView.separated日期卡片点击选中切换颜色问题求助

Flutter日期卡片点击切换背景功能修复方案

核心问题分析

你的代码存在三个关键问题导致点击切换功能失效:

  • selectedCardIndex 和 isSelected 定义在 itemBuilder 内部,每次列表重建时都会被重置为初始值,无法持久化选中状态
  • 点击事件的逻辑只能设置选中索引,没有处理再次点击取消选中的切换逻辑
  • 日期判断重复调用DateFormat,可以优化为直接比较DateTime对象,避免格式化误差

修复步骤与完整代码

  1. 将状态变量移到Widget类的成员变量中,确保状态能被持久化
  2. 修改点击事件逻辑,实现点击切换选中/取消选中的功能
  3. 优化日期判断逻辑,直接对比DateTime对象更准确

修复后的完整代码:

// 在你的State类中添加成员变量
int? _selectedCardIndex; // 使用可空类型,初始为null表示无选中

Container date_card(BuildContext context) {
  return Container(
    height: MediaQuery.of(context).size.height * 0.13,
    width: MediaQuery.of(context).size.width * 1,
    child: ListView.separated(
      scrollDirection: Axis.horizontal,
      itemBuilder: (BuildContext context, int index) {
        // Today date
        DateTime currentDate = DateTime.now();
        // 修正周起始计算:currentDate.weekday默认周一为1,调整为从上周日开始
        DateTime startOfWeek = currentDate.subtract(Duration(days: currentDate.weekday));

        DateTime itemDate = startOfWeek.add(Duration(days: index));
        String formattedDate = DateFormat('d').format(itemDate);
        String formattedDay = DateFormat('E').format(itemDate);

        // 直接对比DateTime对象,避免格式化字符串的误差
        bool isToday = itemDate.year == currentDate.year &&
            itemDate.month == currentDate.month &&
            itemDate.day == currentDate.day;
        bool isSelected = _selectedCardIndex == index;

        return InkWell(
          onTap: () {
            setState(() {
              // 切换选中状态:如果当前索引已选中则取消,否则选中
              if (_selectedCardIndex == index) {
                _selectedCardIndex = null;
              } else {
                _selectedCardIndex = index;
              }
            });
          },
          child: Padding(
            padding: const EdgeInsets.symmetric(vertical: 20),
            child: Card(
              elevation: 2,
              color: isToday
                  ? Color(0xff9a9a9a)
                  : isSelected
                      ? Colors.black
                      : Color(0xffF8F8F8),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10),
              ),
              child: Container(
                height: MediaQuery.of(context).size.height * 0.1,
                width: MediaQuery.of(context).size.width * 0.12,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text(
                      formattedDate,
                      style: TextStyle(
                        fontSize: 18,
                        color: isToday || isSelected
                            ? Colors.white
                            : Colors.black,
                      ),
                    ),
                    Text(
                      formattedDay.toUpperCase(),
                      style: TextStyle(
                        fontSize: 10,
                        color: isToday
                            ? Colors.white
                            : isSelected
                                ? Colors.white // 黑色背景配白色文字优化可读性
                                : Color(0xff8EA0B6),
                      ),
                    ),
                    Text(
                      (isToday && isSelected) ? '˚' : '',
                      style: TextStyle(color: Colors.white),
                    )
                  ],
                ),
              ),
            ),
          ),
        );
      },
      separatorBuilder: (BuildContext context, int index) =>
          SizedBox(width: 4),
      itemCount: 30,
    ));
}

额外优化说明

  • 修正了startOfWeek的计算逻辑,原代码currentDate.weekday +1会导致起始日期偏差,调整后列表从上周日开始显示30天
  • 将选中状态的文字颜色修正为白色,提升黑色背景下的可读性
  • 使用int?类型的_selectedCardIndex,初始值null表示无选中卡片,逻辑更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 07:42:21