Обновление элемента Recyclerview DiffUtil - PullRequest
1 голос
/ 20 февраля 2020

У меня есть бесконечная прокрутка в моем обзоре переработчика, поэтому он будет обновляться при появлении новых данных. и я использую DiffUtil для обновления данных в представлении реселлера. DiffUtil обновляет данные, но всякий раз, когда есть данные для обновления, окно повторного просмотра прокручивается вверх, и это выглядит как «использование notifydatasetchanged ()». Вот мой DiffUtil и мой адаптер для обновления данных.

class ProductDiffUtil(
    val oldProductList: List<ProductModel>, val newProductList: List<ProductModel>
) : DiffUtil.Callback() {

    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return oldProductList[oldItemPosition].id == newProductList[newItemPosition].id
    }

    override fun getOldListSize(): Int = oldProductList.size

    override fun getNewListSize(): Int = newProductList.size

    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return oldProductList[oldItemPosition] == newProductList[newItemPosition]
    }

    override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
        return super.getChangePayload(oldItemPosition, newItemPosition)
    }
}

Вот мой адаптер для обновления данных

fun addProductList(productList: List<ProductModel>?) {
        val diffResult = DiffUtil.calculateDiff(ProductDiffUtil(this.productList, productList!!))
        this.productList.addAll(productList)
        diffResult.dispatchUpdatesTo(this)
    }

, пожалуйста, помогите мне с этим. он работает нормально, когда я использую notifyItemRangeChanged () ... так что я должен использовать, чтобы обновить данные в переработке для лучшей практики.

https://drive.google.com/open?id=1SapXW2wusmTpyGCRA9fa0aSLCYNL1fzN

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

Вы сравниваете предыдущее содержимое только с новыми элементами, а не со списком, в котором все они добавлены.

Представьте себе, если this.productList в настоящее время 1,2,3, и новый productList это 4,5,6. Когда вы запускаете

DiffUtil.calculateDiff(ProductDiffUtil(this.productList, productList!!)

, он будет сравнивать 1 с 4, 2 с 5 и т.д. c. и сделаем вывод, что все изменилось и новые элементы не были добавлены. (примечание: это упрощенное описание алгоритма DiffUtil, но оно служит для иллюстрации сути)

Вместо этого, если вы хотите использовать DiffUtil:

val oldList = ArrayList(productList)
this.productList.addAll(productList)
val diffResult = DiffUtil.calculateDiff(ProductDiffUtil(oldList, productList!!)
diffResult.dispatchUpdatesTo(this)

или, поскольку вы точно знаете, как многие пункты добавлены и где, просто используйте notifyItemRangeInserted и избегайте копирования:

val oldSize = this.productList.size
this.productList.addAll(productList)
notifyItemRangeInserted(oldSize, productList.size)
0 голосов
/ 20 февраля 2020

Проверьте, был ли менеджер компоновки уже настроен и получите текущую позицию прокрутки. Вот так:

var itemPostion= 0
if(myRecyclerView.layoutmanager != null){
  itemPostion = (myRecyclerView.layoutmanager as LinearLayoutManager)
.findFirstCompletelyVisibleItemPosition()
}

Вы можете посмотреть этот пример проекта на GitHub

...