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

Kotlin中RecyclerView点击项变色后无法恢复默认状态问题求助

解决RecyclerView日历项点击后之前选中项无法恢复默认颜色的问题

问题原因

  • 点击事件仅修改当前项的颜色,未触发RecyclerView刷新之前选中的项,导致旧项状态无法更新
  • 点击时直接将select设为当前adapterPosition,使得if (select == adapterPosition)永远成立,else分支从未执行

解决方案

  1. 调整点击事件逻辑:点击时记录旧选中位置,更新新位置后,刷新这两个位置的视图
  2. 在onBind中处理颜色状态:利用RecyclerView的绑定机制,每次绑定视图时根据选中状态设置颜色,适配视图复用

修改后的完整代码

class CalendarAdapter(val clickListener: (CalendarModel) -> Unit) :
    ListAdapter<CalendarModel, CalendarAdapter.CalendarViewHolder>(CalendarDiffUtils()) {
    private var selectedPosition = -1 // 重命名变量,语义更清晰

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CalendarViewHolder {
        val binding =
            CalendarItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return CalendarViewHolder(binding, binding.root)
    }

    override fun onBindViewHolder(holder: CalendarViewHolder, position: Int) {
        holder.onBind(getItem(position), position == selectedPosition) // 传递当前项的选中状态
    }

    override fun getItemViewType(position: Int): Int {
        return position
    }

    inner class CalendarViewHolder(
        private val binding: CalendarItemBinding,
        containerView: View
    ) : RecyclerView.ViewHolder(containerView) {

        fun onBind(dateModel: CalendarModel, isSelected: Boolean) {
            with(dateModel) {
                with(binding) {
                    // 保留原有空日期显示逻辑
                    txtIranianDate.isVisible = iranianDay != EMPTY_DATE
                    txtGregorianDate.isVisible = iranianDay != EMPTY_DATE
                    if (iranianDay == EMPTY_DATE) {
                        return
                    }

                    // 核心:绑定视图时根据选中状态设置颜色
                    val bgColor = if (isSelected) {
                        ContextCompat.getColor(itemView.context, R.color.blue)
                    } else {
                        ContextCompat.getColor(itemView.context, R.color.white)
                    }
                    cardDays.setCardBackgroundColor(bgColor)

                    // 点击事件处理
                    itemView.setOnClickListener {
                        clickListener(dateModel)
                        val oldPosition = selectedPosition
                        selectedPosition = adapterPosition
                        // 刷新旧选中项和新选中项,触发视图重新绑定
                        notifyItemChanged(oldPosition)
                        notifyItemChanged(selectedPosition)
                    }
                }
            }
        }
    }
}

关键修改说明

  • 将select重命名为selectedPosition,提升代码可读性
  • 在onBindViewHolder中传递选中状态,让onBind方法在视图绑定时就处理颜色逻辑,适配RecyclerView的视图复用机制
  • 点击事件中先保存旧选中位置,更新新位置后调用notifyItemChanged刷新两个位置,确保旧选中项重新绑定时恢复默认颜色

内容的提问来源于stack exchange,提问作者Hosein.m.barazandeh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 02:01:16