从recyclerview列表中删除多个项目(包括最后一项)它会抛出错误IndexOutOfBound

问题描述 投票:0回答:2

下面的代码可从 Recyclerview 列表中选择多个项目。

        holder.itemView.setOnLongClickListener(View.OnLongClickListener {

              //  if (selectedPosition == position) {
                 //   selectedPosition = -1
//                    notifyItemChanged(position);
               // }
                selectedPosition = position;
                isSelect = true
                notifyItemChanged(position);
                items.get(position).id?.let { it1 -> deletList.add(it1) 
}

对列表中所选项目位置执行删除操作。

    fun removeSelectedItems(){
    mSelectedItems.sortedDescending()
    mSelectedItems.forEach{ itemIndex ->
        items.removeAt(itemIndex)
        notifyItemRemoved(itemIndex)
        notifyDataSetChanged()
    }
    mSelectedItems.clear()
}

}

在按钮上单击从回收器视图列表中删除所选项目

deletebutton.setOnClickListener {
                   
                    removeSelectedItems()
                    selectedPosition = RecyclerView.NO_POSITION

                }

以任何顺序删除包括最后一项在内的多个项目,直到选择最后一项为止,都会抛出错误索引越界,因为如果最后一项上方的任何项目被删除,列表大小会减小并且索引仍保留在该位置?感谢帮助。

var deletList: ArrayList<String> = ArrayList()
var items: ArrayList<GetListModel>
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OutagesViewHolder {
        return OutagesViewHolder(
            LayoutInflater.from(parent!!.context).inflate(
                R.layout.chats_list_item,
                parent,
                false
            )
        )
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getItemViewType(position: Int): Int {
        return position
    }

    override fun getItemCount(): Int = items.size


    @SuppressLint("NewApi")
    override fun onBindViewHolder(holder: OutagesViewHolder, position: Int) {


        val o: Any = items.get(position)


    holder.itemView.setOnLongClickListener(View.OnLongClickListener {
    
                    if (selectedPosition == position) {
                        selectedPosition = -1
    //                    notifyItemChanged(position);
                    }
                    selectedPosition = position;
                    isSelect = true
                    notifyItemChanged(position);
mSelectedItems.add(selectedPosition)
                        items.get(position).id?.let { it1 -> deletList.add(it1)}
    
}

deletebutton.setOnClickListener {
               
                removeSelectedItems()
                selectedPosition = RecyclerView.NO_POSITION
                holder.itemView.setBackgroundColor(Color.parseColor("#00000000"));

            }
    }

}
android android-studio android-recyclerview android-adapter recyclerlistview
2个回答
2
投票

试试这个

输出

我们可以通过多种方式实现

在适配器中声明一个列表

private var mSelectedItems = arrayListOf<Int>()

在您的视图持有者上选择的索引添加到列表中

holder.itemView.setOnLongClickListener(View.OnLongClickListener {
// Selected item index
mSelectedItems.add(layoutPosition)
}

你的删除功能是这样的

//单个或多个调用同一个函数

fun removeSelectedItems(){
mSelectedItems.sortedDescending()
    mSelectedItems.forEach{itemIndex ->
        YOUR_ITEM_LIST.removeAt(itemIndex)
        notifyItemRemoved(itemIndex)
    }
    mSelectedItems.clear()
}

fun removeSelectedItems(){
    YOUR_ITEM_LIST.removeAll(mSelectedItems)
    notifyDataSetChanged()
    mSelectedItems.clear()
}

如果您有批量记录,请使用 Diffutil...

这是例子 https://developer.android.com/reference/androidx/recyclerview/widget/ListAdapter

您也可以使用普通的 recyclerView 适配器。


0
投票

我也遇到了这个问题,并且必须以非常具体的方式解决它。我删除项目的方式是从适配器本身内部删除的。

  1. 首先,最重要的是在适配器本身中存储回收器视图的实例。
  2. 其次,使用holder.getAdapterPosition()将所选recyclerView项目的位置存储在数组列表中
  3. 第三,在 for 循环中迭代此列表,并使用在第一步中创建的回收器视图实例,使用 recyclerView.findViewHolderForAdapterPosition() 获取每个位置的视图持有者

需要注意的一件事是,您需要首先按升序对第 2 步中的列表进行排序,并且您输入到第 3 步的参数中的位置必须通过您用于 for 循环作为位置的变量来减少适配器中的内容不断变化。

这里我提供了我的示例代码,我使用 viewHolder 来调用我想在删除时调用的某个动画,但不需要使用 viewHolder。

public class Your_Adapter extends RecyclerView.Adapter<Your_Adapter.ViewHolder>{
   private final RecyclerView recyclerView;
   private ArrayList<Integer> selected_Items_position = new ArrayList<>();

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

   holder.container.setOnClickListener(new View.OnClickListener() {
     selected_Items_position.add(holder.getAdapterPosition());
     
     // If you want to unselect the item you will have to implement your 
     // own logic also ull have to use something like selected_Items_position.remove(Integer.valueOf(holder.getAdapterPosition())); to remove the item from the selected list
   }
}

public void removeSelectedItems() {

   ViewHolder holder;
   Collections.sort(selected_Items_position);

   for (int i = 0; i< selected_Items_position.size(); i++) {

     holder = (ViewHolder) recyclerView.findViewHolderForAdapterPosition(selected_Items_position.get(i)-i);
     int actual_position = holder.getAdapterPosition();

     // Alternatively you could directly use 
    //int actual_position = selected_Items_position.get(i) - i;

    bin_items.remove(actual_position);
    holder.item.startAnimation(remove); // Call animation on remove
    notifyItemRemoved(actual_position);
    }
   selected_BinItems_position.clear(); // dont forget this or ull get index out of bounds

}


}

    
}
© www.soinside.com 2019 - 2024. All rights reserved.