RecyclerView滚动后已选中CheckBox变为未选中问题如何解决
问题根因
- RecyclerView采用条目复用机制,滑出可视区域的条目控件会被复用于新进入屏幕的条目,每次条目回到可视区域时都会重新执行
onBindViewHolder方法绑定数据 - 你的现有代码仅在CheckBox点击时触发外部回调,没有同步更新数据源中对应
contact实例的checked属性 - 条目重新绑定时读取的是数据源中未更新的旧
checked值,因此选中状态会被重置为未选中
修复方案
你只需要在CheckBox点击事件中先同步修改数据源的状态即可,修改后的onBindViewHolder代码如下:
override fun onBindViewHolder(holder: viewHolder, position: Int) { val currentItem = list[position] holder.itemView.apply { contact_name.text = currentItem.contactName contact_number.text = currentItem.contactNumber[0] // 先移除旧监听避免复用冲突(可选优化) check_number.setOnClickListener(null) // 先赋值选中状态再设置监听 check_number.isChecked = currentItem.checked check_number.setOnClickListener { // 核心修改:同步更新数据源中的选中状态 currentItem.checked = check_number.isChecked // 触发外部回调 listener(currentItem) } } }
如果你需要在外部处理选中逻辑,也可以保持现有Adapter代码,在外部实现listener回调的时候,修改传入的contact实例的checked属性,再调用adapter.notifyItemChanged(对应位置)刷新条目即可。
额外注意事项
- 不推荐使用
setOnCheckedChangeListener处理CheckBox点击,因为onBindViewHolder中给isChecked赋值时会主动触发该监听,容易引发逻辑混乱,使用setOnClickListener更可控 - 如果列表有增删操作,推荐用
holder.getAbsoluteAdapterPosition()获取真实位置,避免下标错位
内容的提问来源于stack exchange,提问作者Anas Hafidi
相关产品推荐
相关产品推荐

