Зачем нужны методы areItemsTheSame и areContentsTheSame в DiffUtil
Что проверяют
Понимаете ли вы, как DiffUtil решает, какие элементы вставить, удалить, переместить и перерисовать, и зачем для этого две разные проверки. Следом спрашивают про getChangePayload и о том, где считается diff в ListAdapter.
Как отвечать
DiffUtil сравнивает старый и новый список алгоритмом Майерса и превращает разницу в точечные notifyItemInserted, notifyItemRemoved, notifyItemMoved, notifyItemChanged вместо notifyDataSetChanged().
areItemsTheSame: это одна и та же сущность? Сравнивают стабильный идентификатор,old.id == new.id. От ответа зависит, будет элемент считаться перемещённым или удалённым и вставленным заново;areContentsTheSame: вызывается только для пар, где первый метод вернулtrue. Проверяет, изменилось ли то, что видно на экране. Для data class обычно хватаетold == new. ОтветfalseозначаетnotifyItemChangedи повторныйonBindViewHolder;getChangePayload: необязательный метод. Возвращает, что именно изменилось, например только счётчик лайков, иonBindViewHolder(holder, position, payloads)обновляет одно поле без полной перепривязки и мигания;- два API:
DiffUtil.Callbackработает с позициями (oldItemPosition,newItemPosition) и требует размеры списков, аDiffUtil.ItemCallback<T>получает сами элементы и используется вListAdapterиAsyncListDiffer; - поток:
DiffUtil.calculateDiffсинхронный, на больших списках его не зовут на главном потоке.ListAdapter.submitListсчитает diff в фоне сам.
Где спотыкаются
Сравнивают в areItemsTheSame всё содержимое. Любая правка поля превращается в удаление и вставку, анимации дёргаются, а прокрутка прыгает.
Мутируют элементы старого списка и передают в submitList тот же экземпляр. AsyncListDiffer сравнивает списки по ссылке и просто ничего не делает, а если список новый, но объекты те же, старая и новая версии совпадают, и areContentsTheSame вернёт true. Нужны неизменяемые модели и copy().
Путают, какой метод за что отвечает, или думают, что достаточно одного areContentsTheSame. Без идентичности DiffUtil не отличит изменение элемента от замены его другим.