Как обновить позиции RecyclerView после удаления?

#android #kotlin #android-recyclerview

#Android #kotlin #android-recyclerview

Вопрос:

У меня есть представление Recycler с его адаптером и держателем. У каждого элемента есть кнопка «удалить», которая должна обновить recyclerview. Но после удаления первого элемента, когда я пытаюсь удалить другие, из источника данных удаляются элементы со старыми индексами элементов, которые я хочу удалить

Надеюсь, я смогу объяснить это на примере:

Старые данные: (1 2 3 4 5 6 7) -> удаление «1» -> (2 3 4 5 6 7) -> удаление «2» -> (2 4 5 6 7) -> удаление «2» -> (2 5 6 7)

Вот исходный код ViewHolder:

 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   "'"
    }
}
 

Код содержимого:

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

 

Ответ №1:

Чтобы удалить определенное позиционированное значение, я просто вызвал getAdapterPosition() , чтобы указать позицию элемента, которую нужно удалить. Просто попробуйте это в вашем onBindViewHolder с ArrayList, который использует как старые данные: (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)
           
        }
}
 

Ответ №2:

Добавьте приращение в adapterPosition на 1

adapterPosition 1

В качестве альтернативы для повышения производительности вы можете использовать класс DiffUtil, который поможет вычислить изменение позиции элемента.

вы можете ознакомиться с некоторыми руководствами здесь: https://blog.mindorks.com/the-powerful-tool-diff-util-in-recyclerview-android-tutorial