android - Recyclerview DiffUtil 项目更新
问题描述
我的 recyclerview 中有无尽的滚动,所以当有新数据时它会更新。我正在使用 DiffUtil 更新 recyclerview 中的数据。DiffUtil 确实会更新数据,但只要有更新数据,recyclerview 就会滚动到顶部,看起来就像“使用 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() 时它工作正常......所以我应该使用什么来更新 recyclerview 中的数据以获得最佳实践。
https://drive.google.com/open?id=1SapXW2wusmTpyGCRA9fa0aSLCYNL1fzN
解决方案
您仅将先前的内容与新项目进行比较,而不是与添加了所有项目的列表进行比较。
想象一下 ifthis.productList
是 current 1,2,3
,而 new productList
is 4,5,6
。当你跑
DiffUtil.calculateDiff(ProductDiffUtil(this.productList, productList!!)
它将1
与4
、2
to5
等进行比较,并得出结论,一切都发生了变化,并且没有添加新项目。(注意:这是对 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)
推荐阅读
- javascript - 如何将不可删除的日志添加到 Devtools 控制台?
- python - 每次我在刽子手游戏中再次play_again 时,如何才能生成一个新单词?
- excel - Windows 升级后 Excel VBA 的奇怪宏行为
- python - 如何设置 PipelineJob 的运行名称
- mongodb - 通过mongoDB中的元素字段获取具体元素
- c# - 使用服务帐户通过 Google 身份验证获取 Youtube 流
- python - Python中数据集的第一次分析-多标准
- c# - 在图片框中查看保存为字符串的图像
- ruby-on-rails - 在 Rails 中跟踪 sidekiq 作业
- c# - C# WPF 应用程序 - 在运行时修改数据表的问题 - System.ArgumentOutOfRangeException