arraylist.remove(element) 函数是否有替代方法?

is there any alternate for arraylist.remove(element) function?

我的回收器视图重新加载微调器值,selected 数据存储在全局数组列表中,这是我的回收器视图代码来执行 selection 和 deselect离子。选择和 deselection 工作得很好,但是当我 select 和 change spinner value,然后来返回原始微调器值,其中项目已经 selected,取消选择发生,但项目未从全局数组列表中删除。 在调试时我发现光标到达那里,但是我不知道为什么 .remove() 不工作。有没有其他选择或者我做错了吗?有什么我应该知道的,为什么没有删除该项目。

。 . .

class RecyclerViewAdapter(val dataList:ArrayList<ModelClass>,val onItemClicked: (Int) -> Unit):RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {

 object ob {
     val dataSelected = ArrayList<ModelClass>()
     val hm = HashMap<ModelClass,String>()


 }


 fun setData(listModel: List<ModelClass>) {
     dataList.clear()
     dataList.addAll(listModel)
     notifyDataSetChanged()

 }


 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
     val binding = ItemViewBinding.inflate(
         LayoutInflater.from(parent.context), parent, false
     )
     return ViewHolder(binding, parent.context)
 }


 @SuppressLint("ResourceAsColor")
 override fun onBindViewHolder(holder: ViewHolder, position: Int) {

     holder.bindItems(dataList[position])

 }

 override fun getItemCount() = dataList.size

 inner class ViewHolder(
     val binding: ItemViewBinding,
     val context: Context
 ) : RecyclerView.ViewHolder(binding.root) {

     var count=0
     @SuppressLint("ResourceAsColor")
     fun restore() {


         for (i in 0 until ob.dataSelected.size) {
             for (j in 0 until dataList.size) {
                 if (ob.dataSelected[i].sku_code == (dataList[j]).sku_code) {
                     if (adapterPosition == j) {

                         itemView.isSelected = true
                         itemView.setBackgroundColor(R.color.black)
                         count=count+1
                         println("****")

                     }

                 }

             }
         }

         if(!itemView.isSelected){

                 itemView.isSelected = false
                 itemView.setBackgroundResource(0)


         }
     }

     @SuppressLint("ResourceAsColor", "ResourceType")
     fun bindItems(data: ModelClass) = with(binding) {


         binding.itemQuant.text = data.item_quant
         binding.itemName.text = data.item_name
         binding.mfgName.text = data.mfg
         binding.quantity.text = data.item_stock.toString()


         count=0

         restore()
         itemView.setOnClickListener {

            count += 1
             var isPresent:Int
             if (count%2 == 0){
                 isPresent=1
             }
             else
             {
                 isPresent=0
             }


             if (isPresent == 1) {
                 it.setBackgroundResource(0)  //works
                 ob.dataSelected.remove(dataList[adapterPosition]) //doesnt work if spinner value is changed and changed back. works while still on same screen.

             } else {
                 if (isPresent == 0) {
                     it.setBackgroundColor(R.color.black)


                     ob.dataSelected.add(dataList[adapterPosition])
                     
                }
                 // onItemClicked.invoke(adapterPosition)
             }

         }

     }
 }

}

更改此行

ob.dataSelected.add(dataList[adapterPosition])

至此

ob.dataSelected.add(dataList[adapterPosition].copy)

之后别忘了调用 notfiyDatasetChanged()

你确定它没有被删除吗?您是否设置了断点并检查了数组的内容(或只是记录了它)?因为当您绑定视图持有者时,您只需检查项目是否在 dataSelected 中,如果是,则设置视图的 selectedbackgroundColor 值。如果 dataSelected 不是 ,那么您似乎不会将它们改回来,因此 selected 外观“粘”。

您似乎正在尝试用这个重置它们:

if(!itemView.isSelected){
    itemView.isSelected = false
    itemView.setBackgroundResource(0)
}

但这仅在 itemView.selected 未设置为 true 时有效,如果您的项目在 dataSelected 中,则设置为 true。你需要这样做:

 for (i in 0 until ob.dataSelected.size) {
     for (j in 0 until dataList.size) {
         // rolling multiple conditions into a single value makes it easier to do an if/else
         val selected = ob.dataSelected[i].sku_code == (dataList[j]).sku_code && adapterPosition == j
         if (selected) {
             itemView.isSelected = true
             itemView.setBackgroundColor(R.color.black)
             count=count+1
             println("****")
         } else {
             itemView.isSelected = false
             itemView.setBackgroundResource(0)
         }

     }
 }

这样您就总是更新视图持有者的内容以反映当前项目的状态。这在 RecyclerViews 中尤为重要,因为这些要点是 ViewHolders 被重用以显示不同的项目,以及绑定时未设置的任何 View 属性(例如颜色, 复选框状态)在显示其他项目时将保持上次设置的状态。


顺便说一句,您可以通过检查 dataSelected 中是否有您要查找的 SKU 来简化循环情况:

val itemSku = datalist[adapterPosition].sku_code
val selected = ob.dataSelected.any { it.sku_code == itemSku }

理想情况下,您也不会使用 adapterPosition 来查找当前项目 - 您正在匹配的项目被传递给 bindItems(如 data),您可以只需将其传递给您的 restore 函数


编辑 如果项目 没有 dataSelected 中删除,我猜这是因为你的对象从 dataList 重新获取 dataSelected 中的“不存在”。 “不存在”是指不存在 equals 您要 remove.

的对象
ob.dataSelected.remove(dataList[adapterPosition])

我假设可能是这种情况,因为当您检查某个项目是否在所选数组中时,您没有进行直接对象比较,而是专门比较它们的 sku_code

if (ob.dataSelected[i].sku_code == (dataList[j]).sku_code)

如果您不能只执行 if (obj.dataSelected[i] == dataList[j]),那么 remove 也不会起作用 - 这是相同的检查。因此,也许您需要考虑使这些对象相等(例如,如果这适用于您正在做的事情,则使用数据 类),或者将 removeAll 与谓词一起使用(remove 仅适用于特定项目):

ob.dataSelected.removeAll { it.sku_code == dataList[adapterPosition].sku_code }

您仍然会遇到 UI 未更新的问题,就像答案的第一部分所解释的那样!所以你这里可能有两个问题