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

自定义RecyclerViewAdapter勾选CheckBox后无法删除多选列表项问题求助

RecyclerView多选批量删除功能问题排查

核心问题列表

  • 选中列表selectedList未初始化,直接赋值为null,所有添加选中条目的逻辑完全不执行,导致删除时拿不到任何选中数据
  • CheckBox选中监听逻辑缺失:仅处理了选中时添加条目的逻辑,未处理取消选中时移除条目的逻辑,会导致取消勾选的条目仍然留在选中列表中
  • 未同步修改TestModel的isSelected属性:绑定ViewHolder时用model.isSelected给CheckBox赋值,但选中状态变化时没有同步修改model的属性,RecyclerView滚动复用条目时会出现CheckBox状态错乱的问题
  • 删除逻辑完成后未清空选中列表:已删除的条目会残留在selectedList中,下次执行删除操作时会重复处理无效数据
  • 遍历选中列表删除元素时存在并发修改异常风险:直接遍历原始selectedList的同时修改数据源,极端情况下会触发遍历异常
  • 若TestModel未重写equals和hashCode方法,列表的匹配逻辑会按内存地址判断,若数据源更新时生成了新的对象实例,会出现无法匹配到待删除条目、删除失败的问题

修复代码

修复后的TestAdapter代码

class TestAdapter(var isSelectingEnabled: Boolean) : RecyclerViewBaseAdapter<TestModel>() {

    // 初始化选中列表,改为非空类型
    val selectedList = arrayListOf<TestModel>()
    override fun getLayoutResId(viewType: Int): Int = R.layout.test_list_item
    var onItemClick: ((TestModel) -> Unit)? = null

    override fun bindData(
        holder: SimpleViewHolder<TestModel>,
        model: TestModel,
        position: Int
    ) {
        val checkBox = holder.itemView.findViewById<MaterialCheckBox>(R.id.checkbox)
        holder.itemView.setOnClickListener {
            onItemClick?.invoke(model)
        }

        checkBox.apply {
            setOnCheckedChangeListener(null)
            isChecked = model.isSelected
            isVisible = isSelectingEnabled

            setOnCheckedChangeListener { _, isChecked ->
                // 同步修改model的选中状态
                model.isSelected = isChecked
                if (isChecked) {
                    selectedList.add(model)
                } else {
                    selectedList.remove(model)
                }
            }
        }
    }

    // 新增切换选择模式时重置状态的方法,避免状态残留
    fun toggleSelectMode(enable: Boolean) {
        isSelectingEnabled = enable
        if (!enable) {
            selectedList.clear()
            dataList.forEach { it.isSelected = false }
            notifyDataSetChanged()
        }
    }
}

修复后的Fragment删除逻辑代码

private fun removeListItems() {
    if (!testAdapter.isSelectingEnabled) {
        testAdapter.removeAllItems(arrayList)
        arrayList.clear()
        binding.buttonBulkAddRemove.isEnabled = false
    } else {
        if (testAdapter.selectedList.isNotEmpty()) {
            // 先复制一份选中列表再遍历,避免并发修改异常
            val toRemoveList = testAdapter.selectedList.toList()
            toRemoveList.forEach {
                if (arrayList.contains(it)) {
                    testAdapter.removeItems(it)
                    arrayList.remove(it)
                }
            }
            // 删除完成后清空选中列表
            testAdapter.selectedList.clear()
        }
    }
}

内容的提问来源于stack exchange,提问作者Anshul Tyagi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:54:03