androidandroid-studioandroid-recyclerviewandroid-adapterrecyclerlistview

Deletion of multiple items(Including last item) from recyclerview list It throws error IndexOutOfBound


Below code to select multiple items from the Recyclerview list.

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

performing delet action on the list on selected item position.

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

}

On ButtonClick deleting the selected items from recycler view list

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

                }

Deleting multiple item including last item in any order until last item is selected it is throwing error index out of bound because if any item above last item get deleted list size decreases and index still remains at position? help is appreciated.

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"));

            }
    }

}

Solution

  • Try this

    Output

    enter image description here

    We can achieve multiple way

    Declare a list in your adapter

    private var mSelectedItems = arrayListOf<Int>()
    

    On your view holder chosen index add to the list

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

    Your delete function like this

    //Single or multiple call this same function

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

    OR

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

    OR

    If you've bulk record go with Diffutil...

    Here is the example https://developer.android.com/reference/androidx/recyclerview/widget/ListAdapter

    You can use normal recyclerView adapter as well.