DiffUtil.Callback 未按预期工作

Mot*_*tov 8 android android-recyclerview android-diffutils android-listadapter

我正在使用 DiffUtil.ItemCallback 和 ListAdapter 来更新 RecyclerView。

它工作得很好,但它的行为让我感到困扰。

根据文档,areContentsTheSame只有在areItemsTheSame返回时才应调用该方法true

从文档:

仅当 areItemsTheSame(int, int) 为这些项目返回 true 时才调用此方法。

但是,就我而言,在使用新列表更新列表时,如下所示:

adapter.submitList(items.toMutableList())
Run Code Online (Sandbox Code Playgroud)

DiffUtil.ItemCallback 确实被触发,但即使areItemsTheSame返回true它也不会立即调用areContentTheSame(如预期的那样?),而是areItemsTheSame在不同的对象对上一次又一次地调用,(我在那里使用了带有断点的调试器)。经过areItemsTheSame几次调用并返回true,最后它会调用areContentTheSame,有时,我看到传递给的对象areContentTheSame实际上不一样!!并且有不同的id!!这意味着areContentTheSame甚至不应该调用这些对!

这是我的 DiffUtilCallback 的实现方式:

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
   }
}
Run Code Online (Sandbox Code Playgroud)

另外,在运行这个时,在 logcat 中我看到很多调用areItemsTheSamewithtrue但很少areContentTheSame

这是预期的行为吗?