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,以获得更清晰、更健壮的代码。但这涉及到更多的改变,而且在这里的答案中要讨论的太多了。您可以通过网络搜索有关这些主题的文章来了解这些主题。
我正在尝试检查 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,以获得更清晰、更健壮的代码。但这涉及到更多的改变,而且在这里的答案中要讨论的太多了。您可以通过网络搜索有关这些主题的文章来了解这些主题。