我正在使用 DiffUtil.ItemCallback 和 ListAdapter 来更新 RecyclerView。
它运行得很好,但它的行为有些让我困扰。
根据文档,areContentsTheSame
仅当以下情况时才应该调用方法areItemsTheSame
回报true
.
从文档中:
仅当 areItemsTheSame(int, int) 对于这些项目返回 true 时,才会调用此方法。
但是,就我而言,当使用新列表更新列表时,如下所示:
adapter.submitList(items.toMutableList())
DiffUtil.ItemCallback 确实会触发,但即使在areItemsTheSame
回报true
它不会打电话areContentTheSame
马上(如预期?)但是,areItemsTheSame
在不同的对象对上一次又一次地调用(我在那里使用了带有断点的调试器)。
后areItemsTheSame
调用了几次并返回true,最后它确实调用了areContentTheSame
有时,我看到交付的物品areContentTheSame
其实不一样!!并且有不同的id!!这意味着areContentTheSame
甚至不应该打电话给这两对!
这就是我的 DiffUtil 回调的实现方式:
class AppDiffCallback : DiffUtil.ItemCallback<Item?>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
Timber.i("areItemsTheSame: called..")
if (oldItem.getItemType() == newItem.getItemType()) {
Timber.i("areItemsTheSame: done true..")
return true
}
Timber.w("areItemsTheSame: done false..")
return false
}
override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
Timber.i("areContentsTheSame: called")
if(oldItem.getItemType() != newItem.getItemType()){
Timber.w("areContentsTheSame: itemsNotTheSame WTF???}")
return false
}
return when (oldItem.getItemType()) {
Item.HEADER -> checkHeaderContent(oldItem = oldItem as ItemHeader, newItem = newItem as ItemHeader)
Item.ITEM_ACTION -> checkItemContent(oldItem = oldItem as ItemAction, newItem = newItem as ItemAction)
else -> false
}
}
private fun checkHeaderContent(oldItem: ItemHeader, newItem:
ItemHeader): Boolean {
val itemContentTheSame = oldItem.date.toDate().time ==
newItem.date.toDate().time
return itemContentTheSame
}
private fun checkItemContent(oldItem: ItemAction, newItem: ItemAction): Boolean {
val itemContentTheSame = oldItem.action == newItem.action
return itemContentTheSame
}
}
此外,运行此程序时,在 logcat 中我看到许多调用areItemsTheSame
with true
但很少areContentTheSame
这是预期的行为吗?