How to update RecyclerView positions after deleting?

Viewed 534

I Have Recycler view with its adapter and holder. Each element has "delete" button, which has to update recyclerview. But after deleting first element, when I'm trying to delete others, from datasource are removing items with old indices of items, which I want to delete

Hope, I can explain it with an example:

Old data: (1 2 3 4 5 6 7) -> deleting "1" -> (2 3 4 5 6 7) -> deleting "2" -> (2 4 5 6 7) -> deleting "2" -> (2 5 6 7)

Here is ViewHolder source code:

inner class ViewHolder(binding: RecyclerItemBinding) : RecyclerView.ViewHolder(binding.root) {
    val idView: TextView = binding.itemNumber
    val contentView: Button = binding.deleteButton

    init {
        contentView.setOnClickListener {
            removeAt(adapterPosition)
        }
    }

    private fun removeAt(position: Int) {
        values.removeAt(position)
        notifyItemRemoved(position)
        notifyItemRangeChanged(position, itemCount)
        Log.d(TAG, "remove $position left $itemCount")
    }

    override fun toString(): String {
        return super.toString() + " '" + contentView.text + "'"
    }
}

Content code:

object PlaceholderContent {

    /**
     * An array of sample (placeholder) items.
     */
    val ITEMS: MutableList<PlaceholderItem> = ArrayList()

    /**
     * A map of sample (placeholder) items, by ID.
     */
    private val ITEM_MAP: MutableMap<Int, PlaceholderItem> = HashMap()

    private val deletedNumbers : Queue<Int> = LinkedList()

    private const val INITIAL_COUNT = 15

    private var biggest: Int

    init {
        // Add some sample items.
        for (i in 1..INITIAL_COUNT) {
            addItem(createPlaceholderItem(i))
        }
        biggest = ITEMS.last().id
    }

    fun size() : Int = ITEMS.size

    fun addNext() {
        addItem(createPlaceholderItem(deletedNumbers.poll() ?: ++biggest))
        Log.d(TAG, "add $biggest")
    }

    fun removeAt(position: Int) {
        val toRemove = ITEMS.removeAt(position)
        if (toRemove.id == biggest) {
            biggest--
        }
        deletedNumbers.add(toRemove.content.toInt())
    }

    private fun addItem(item: PlaceholderItem) {
        ITEMS.add(item)
        ITEM_MAP[item.id] = item
    }

    private fun createPlaceholderItem(position: Int): PlaceholderItem {
        return PlaceholderItem(size(), "$position")
    }

    /**
     * A placeholder item representing a piece of content.
     */
    data class PlaceholderItem(val id: Int, val content: String): Comparable<PlaceholderItem> {
        override fun toString(): String = content
        override fun compareTo(other: PlaceholderItem): Int = this.id.compareTo(other.id)
    }
    private const val TAG = "PLACEHOLDER_CONTENT"
}

2 Answers

To remove a specific positioned value, I just called the getAdapterPosition() to specify the item position to be removed. Simply try this in your onBindViewHolder with the arrayList that is using like Old data: (1 2 3 4 5 6 7).

override fun onBindViewHolder(holder: RecyclerViewAdapter.ViewHolder, position: Int) {

   holder.buttonDelete2.setOnClickListener {
            arrayList.removeAt(holder.adapterPosition)
            notifyItemRemoved(holder.adapterPosition)
           
        }
}
Related