Android- 检查多个项目并从 RecyclerView 列表中删除

Android- Check multiple items and delete from list of RecyclerView

我正在尝试检查 RecyclerView 中的多个项目并删除它们,但在自定义 RecyclerViewAdapter 中检查 CheckBox 后无法删除。

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

 val selectedList: ArrayList<TestModel>? = null
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 context = holder.itemView.context
    val checkBox = holder.itemView.findViewById<MaterialCheckBox>(R.id.checkbox)
    holder.itemView.setOnClickListener {
        onItemClick?.invoke(model)
    }

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

        setOnCheckedChangeListener { buttonView, isChecked ->
            selectedList?.add(model)
        }
    }

  }
} 

在片段中:

private fun removeListItems() {
    if (!testAdapter.isSelectingEnabled) {
        testAdapter.removeAllItems(arrayList)
        arrayList.clear()
        binding.buttonBulkAddRemove.isEnabled = false
    } else {
        if (arrayList.size > 0) {
            testAdapter.selectedList?.forEach {
                if (arrayList.contains(it)) {
                    testAdapter.removeItems(it)
                    arrayList.remove(it)
                }
            }
        }
    }
}

BaseAdapter class 中定义了几个方法:

fun removeItems(model: T): Boolean {
    val index = dataList.indexOf(model)
    val removed = dataList.remove(model)
    if (removed) {
        notifyItemRemoved(index)
    }
    return removed
}

fun removeAllItems(listItems: List<T>) {
    dataList.removeAll(listItems)
    notifyDataSetChanged()
}

如果我做错了什么,请指导我。

您的 selectedList 为空。你应该使用 val selectedList = mutableListOf<TestModel>().

此外,您可能希望在未选中时从列表中删除项目。

然而,在我看来,你应该改变你的策略。 selectedList 要与您的 UI 状态保持同步会很棘手,尤其是在屏幕旋转之后。相反,您可以简单地迭代适配器的源列表并删除 isSelected 的项目。然后将更改通知 Adapter。

我想该列表在您的基本适配器中 class,但您没有显示。使用重复的 notifyRangeRemoved 调用会有点复杂,或者您可以使用 notifyDataSetChanged() 并忍受列表的丑陋刷新。如果您使用 ListAdapter 作为基础 class.

会更容易

根据更新的问题编辑:

快速而肮脏的解决方案:从您的适配器中删除 selectedItems 以及所有与之交互的代码。将这样的函数添加到 TestAdapter 并在您的 Fragment 中使用它:

fun removeAllCheckedItems() {
    dataList.filter { it.isSelected }
        .forEach { removeItems(it) }
}

更改您已检查的更改侦听器以实际更新您的模型项。无论如何你都需要这样做,否则当他们滚动离开屏幕并返回时,他们会显示错误的复选框状态。

setOnCheckedChangeListener { buttonView, isChecked ->
    model.isChecked = isChecked
}

但是,我建议使用只读列表、不可变模型 class 和 ListAdapter,以获得更清晰、更健壮的代码。但这涉及到更多的改变,而且在这里的答案中要讨论的太多了。您可以通过网络搜索有关这些主题的文章来了解这些主题。