RecyclerView搭配CheckBox选中状态滚动后无法保留问题求助
RecyclerView复选框选中状态不保留的修复方案
问题根源
- 数据重复填充:
onResume方法中每次都会添加100条数据,导致列表数据不断重复累加,且未通知适配器更新数据。 - ViewHolder复用监听冲突:每次绑定
ViewHolder时直接设置OnCheckedChangeListener,复用旧ViewHolder时,设置isChecked会触发残留的旧监听,错误修改其他条目的选中状态。
修复步骤
1. 修正数据填充逻辑
确保数据只初始化一次,避免重复添加,并在填充后通知适配器更新:
override fun onResume() { super.onResume() if (items.isEmpty()) { for (i in 1..100) { items.add(Item("Item $i", false)) } adapter.notifyDataSetChanged() } }
2. 修复复选框监听逻辑
在设置复选框状态前先移除旧的监听,避免复用触发错误回调:
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val item = items[position] holder.textView.text = item.description // 先清除旧监听,防止复用触发错误回调 holder.checkBox.setOnCheckedChangeListener(null) // 设置当前条目选中状态 holder.checkBox.isChecked = item.isSelected // 绑定新的监听,更新数据状态 holder.checkBox.setOnCheckedChangeListener { _, isChecked -> item.isSelected = isChecked } }
或者改用OnClickListener(更简洁,不会因设置isChecked触发回调):
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val item = items[position] holder.textView.text = item.description holder.checkBox.isChecked = item.isSelected holder.checkBox.setOnClickListener { item.isSelected = holder.checkBox.isChecked } }
完整修改后的代码
class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private lateinit var adapter: MyAdapter private val items = mutableListOf<Item>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) adapter = MyAdapter() binding.recyclerView.adapter = adapter } override fun onResume() { super.onResume() if (items.isEmpty()) { for (i in 1..100) { items.add(Item("Item $i", false)) } adapter.notifyDataSetChanged() } } inner class MyAdapter : RecyclerView.Adapter<MyViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false) return MyViewHolder(view) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val item = items[position] holder.textView.text = item.description holder.checkBox.setOnCheckedChangeListener(null) holder.checkBox.isChecked = item.isSelected holder.checkBox.setOnCheckedChangeListener { _, isChecked -> item.isSelected = isChecked } } override fun getItemCount(): Int { return items.size } } inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val textView: TextView = itemView.findViewById(R.id.textView) val checkBox: CheckBox = itemView.findViewById(R.id.checkBox) } data class Item(val description: String, var isSelected: Boolean) }
内容的提问来源于stack exchange,提问作者Anderson Gabriel Ferreira
相关产品推荐
相关产品推荐

