I have endless scroll in my recyclerview, so, it will update when there is new data. and i am using DiffUtil to update data in the recyclerview. DiffUtil does updates the data but whenever there is update data, recyclerview scroll to top and what it looks like is "using the notifydatasetchanged()". here is my DiffUtil and my adapter to update data.
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)
}
}
Here is my adapter to update data
fun addProductList(productList: List<ProductModel>?) {
val diffResult = DiffUtil.calculateDiff(ProductDiffUtil(this.productList, productList!!))
this.productList.addAll(productList)
diffResult.dispatchUpdatesTo(this)
}
please help me with this. it is working fine when i am using notifyItemRangeChanged()... so what should i use to update data in recyclerview for best practice.
https://drive.google.com/open?id=1SapXW2wusmTpyGCRA9fa0aSLCYNL1fzN
You're comparing the previous contents against only the new items, rather than against the list with all of them added.
Imagine if this.productList
is currently 1,2,3
, and the new productList
is 4,5,6
. When you run
DiffUtil.calculateDiff(ProductDiffUtil(this.productList, productList!!)
It will compare 1
to 4
, 2
to 5
, etc. and conclude that everything has changed and no new items have been added. (note: this is an oversimplification of the DiffUtil algorithm, but serves to illustrate the point)
Instead, if you want to use DiffUtil:
val oldList = ArrayList(productList)
this.productList.addAll(productList)
val diffResult = DiffUtil.calculateDiff(ProductDiffUtil(oldList, productList!!)
diffResult.dispatchUpdatesTo(this)
or, since you know exactly how many items are added and where, just use notifyItemRangeInserted
and avoid the copy:
val oldSize = this.productList.size
this.productList.addAll(productList)
notifyItemRangeInserted(oldSize, productList.size)