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

RecyclerView搭配CheckBox选中状态滚动后无法保留问题求助

RecyclerView复选框选中状态不保留的修复方案

问题根源

  1. 数据重复填充:onResume方法中每次都会添加100条数据,导致列表数据不断重复累加,且未通知适配器更新数据。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:05:29