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

Posted

技术标签:

【中文标题】Android-检查多个项目并从 RecyclerView 列表中删除【英文标题】:Android- Check multiple items and delete from list of RecyclerView 【发布时间】:2021-12-24 04:00:19 【问题描述】:

我正在尝试检查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 类中定义了几个方法:

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()

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

【问题讨论】:

【参考方案1】:

您的selectedList 为空。你应该使用val selectedList = mutableListOf&lt;TestModel&gt;()

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

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

我猜该列表在您未显示的基本适配器类中。使用重复的notifyRangeRemoved 调用会有点复杂,或者您可以使用notifyDataSetChanged() 并遭受列表的丑陋刷新。如果您使用 ListAdapter 作为基类会更容易。


编辑,基于更新的问题:

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

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

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

setOnCheckedChangeListener  buttonView, isChecked ->
    model.isChecked = isChecked

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

【讨论】:

是的,你完全理解了这个要求,如果你能告诉我如何从适配器通知片段会很好。 查看我重写的答案。关于如何在更改列表后刷新 RecyclerView 存在许多问题,但我认为使用 ListAdapter 更好。您可以查找有关此的教程。 用更多代码更新问题,请刷新。它可能会清除你的一切。在这里,我能够成功使用“removeAllItems”,但仅面临选定项目的问题。我无法针对一种情况更新完整的基本适配器。 我在答案中添加了更新。 感谢您的建议。最后我在不更新现有适配器的情况下实现了所有场景:)

以上是关于Android-检查多个项目并从 RecyclerView 列表中删除的主要内容,如果未能解决你的问题,请参考以下文章

PHP性能检查用户权限并从其他服务器获取文件

如何从android studio中的recycler视图将数据添加到SQLite数据库中

使用 Grid Layout Manager 等间距的 Android Recycler 视图不起作用

无法从firebase数据库android,recycler视图中检索数据

Android recycler view onItemClick 识别适配器

Android - 为啥 Recycler 视图未显示在设备上? .我认为我的代码是正确的,但视图没有显示