DiffUtil.Callback не работает должным образом - PullRequest
0 голосов
/ 17 июня 2019

Я использую 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, на самом деле не совпадают !!и имеет другой идентификатор!это означает, что 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
   }
}

Кроме того, при запуске этого сообщения в logcat я вижу много вызовов areItemsTheSame с true, но очень мало areContentTheSame

Это ожидаемое поведение?

...