В чем отличие ListAdapter от RecyclerView.Adapter
Что проверяют
Понимаете ли вы, что ListAdapter это надстройка над обычным адаптером, которая сама считает разницу списков, и знаете ли её подводные камни. Следом обычно просят написать DiffUtil.ItemCallback или объяснить, почему после submitList список не обновился.
Как отвечать
androidx.recyclerview.widget.ListAdapter наследуется от RecyclerView.Adapter и внутри использует AsyncListDiffer. Разница в том, кто отвечает за обновления:
RecyclerView.Adapter: данные храните вы и после изменения сами вызываетеnotifyItemInserted,notifyItemRangeChangedи другие. Ошибка в индексах даёт падение или «прыгающий» список.notifyDataSetChanged()проще, но перерисовывает всё и убивает анимации;ListAdapter: вы передаёте новый список вsubmitList(), адаптер считает разницу черезDiffUtilв фоновом потоке и сам рассылает точечные уведомления с анимациями. Элемент берётся черезgetItem(position), текущие данные лежат в неизменяемомcurrentList;DiffUtil.ItemCallback:areItemsTheSameсравнивает идентичность, обычно поid, аareContentsTheSameсравнивает содержимое, для Kotlindata classхватает==.
submitList асинхронный: сразу после вызова currentList ещё старый. Если после обновления нужно прокрутить список к началу, используйте перегрузку с колбэком submitList(list) { ... }.
RecyclerView.Adapter напрямую уместен, когда данные не укладываются в модель «список, который целиком заменяется», например при нескольких источниках или ручном управлении позициями. Для постраничной загрузки есть PagingDataAdapter из Paging 3 с тем же подходом к диффам.
Где спотыкаются
Меняют элементы или сам список на месте и передают тот же экземпляр в submitList. Если ссылка совпала со старой, дифф не запускается, а если объекты мутированы, areContentsTheSame сравнивает объект сам с собой. Передавайте новый список с новыми объектами.
В areItemsTheSame сравнивают объекты целиком. Любое изменение содержимого тогда выглядит как удаление и вставка, и анимация получается неправильной.
Путают с android.widget.ListAdapter, интерфейсом для старого ListView: имя одно, классы разные.