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

如何在RecyclerView适配器中获取今日位置并设置日期文本颜色

解决RecyclerView日历中日期颜色区分的问题

我明白你遇到的问题了——原来的代码里试图用布尔值day.isToday和position做比较,这肯定会报错,因为类型完全不匹配。我们需要换个思路:先找到今日在数据源列表中的位置,或者直接比较日期本身,来判断当前日期是在今日之前还是之后,再设置对应的颜色。

方案一:通过数据源索引判断(适合数据源按日期顺序排列的场景)

首先在适配器中定位今日在数据源里的索引,绑定数据时对比当前日期的索引和今日索引即可:

  1. 在适配器类中新增变量存储今日的索引:
private var todayIndex = -1 // 默认-1表示未找到今日数据
  1. 在init块中遍历数据源,找到今日对应的位置:
init {
    firstDayDayOfWeek = items[0].dayOfWeek
    totalDays = items.size
    // 找到今日在items列表中的索引
    todayIndex = items.indexOfFirst { it.isToday }
}
  1. 修改bind方法中的颜色判断逻辑:
    把原来错误的if (position < day.isToday)替换成:
// 获取当前日期在items列表中的索引
val currentDayIndex = position - 7 - firstDayDayOfWeek
// 判断当前日期是否在今日之前
if (todayIndex != -1 && currentDayIndex < todayIndex) {
    // 今日之前的日期,设置灰色
    dayTxt.setTextColor(ContextCompat.getColor(context, R.color.gray))
} else {
    // 今日及之后的日期,设置黑色
    dayTxt.setTextColor(ContextCompat.getColor(context, R.color.black))
}

方案二:直接比较日期(更健壮,推荐)

如果你的DayEntity类包含日期相关字段(比如时间戳date: Long或者LocalDate对象),直接比较日期会更可靠,能避免索引可能出现的偏差:

  1. 在适配器中新增变量存储今日的日期:
private var todayDate: Long? = null // 假设用Long类型时间戳,可根据实际字段调整
  1. 在init块中取出今日的日期:
init {
    firstDayDayOfWeek = items[0].dayOfWeek
    totalDays = items.size
    // 取出今日的日期值
    items.find { it.isToday }?.let { todayDate = it.date }
}
  1. 修改bind方法中的颜色判断:
if (todayDate != null && day.date < todayDate!!) {
    // 今日之前的日期,设置灰色
    dayTxt.setTextColor(ContextCompat.getColor(context, R.color.gray))
} else {
    // 今日及之后的日期,设置黑色
    dayTxt.setTextColor(ContextCompat.getColor(context, R.color.black))
}

修改后的完整适配器代码(以方案一为例)

class DaysAdapter constructor(val context: Context, private val items: MutableList<DayEntity>) :
    RecyclerView.Adapter<DaysAdapter.ViewHolder>() {

    private val TYPE_HEADER = 0
    private val TYPE_DAY = 1
    private var firstDayDayOfWeek = 0
    private var totalDays = 0
    private var todayIndex = -1 // 新增:存储今日在items中的索引

    init {
        firstDayDayOfWeek = items[0].dayOfWeek
        totalDays = items.size
        // 找到今日的索引
        todayIndex = items.indexOfFirst { it.isToday }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return ViewHolder(inflater.inflate(R.layout.item_day_new, parent, false))
    }

    override fun getItemCount() = 7 * 7

    override fun getItemViewType(position: Int): Int {
        return if (isPositionHeader(position)) {
            TYPE_HEADER
        } else {
            TYPE_DAY
        }
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(position)

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val dayTxt = itemView.findViewById(R.id.dayTxt) as TextView

        //Bind data
        fun bind(pos: Int) {
            var position = pos
            position += 6 - (position % 7) * 2

            if (totalDays < position - 6 - firstDayDayOfWeek) {
                return
            } else {
                //Day
                if (!isPositionHeader(position)) {
                    if (position - 7 - firstDayDayOfWeek >= 0) {
                        val currentDayIndex = position - 7 - firstDayDayOfWeek
                        val day = items[currentDayIndex]
                        dayTxt.isVisible = true
                        dayTxt.text = day.num
                        
                        // 修正后的颜色判断逻辑
                        if (todayIndex != -1 && currentDayIndex < todayIndex) {
                            dayTxt.setTextColor(ContextCompat.getColor(context, R.color.gray))
                        } else {
                            dayTxt.setTextColor(ContextCompat.getColor(context, R.color.black))
                        }
                    } else {
                        dayTxt.isVisible = false
                    }
                } else {
                    //Header
                    dayTxt.text = Constants.FIRST_CHAR_OF_DAYS_OF_WEEK_NAME[position]
                }
            }
        }
    }

    private fun isPositionHeader(position: Int) = position < 7
}

补充说明

  • 原来的代码错误核心:day.isToday是布尔值(true/false),而position是整数,两者属于不同类型,无法直接比较。我们需要的是定位今日在数据源中的位置,或者直接对比日期实体的时间属性。
  • 如果你的日历数据源是严格按日期顺序排列的,方案一足够使用;如果担心数据源调整导致索引出错,方案二的日期直接对比会更稳妥。

内容的提问来源于stack exchange,提问作者Dr.KeyOk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:56:14