Предварительное условие: чтобы получить максимальную отдачу от этой статьи, вы должны быть знакомы с концепцией RecyclerView в разработке для Android.

Список - это обычная функция в приложениях Android. Понимание того, как оптимизировать его реализацию, чтобы обеспечить безупречный пользовательский интерфейс, является очень важной частью разработки под Android.

Что такое DiffUtil?

DiffUtil - служебный класс. Он берет два списка (состоящий из старого списка и нового списка) и сравнивает их. Он использует алгоритм под названием алгоритм различий Юджина В. Майерса для определения минимального количества изменений, которые необходимо внести в старый список для создания нового списка.

Интересный факт: я узнал, что алгоритм различия Юджина В. Майерса является алгоритмом сравнения по умолчанию, используемым Git. Вы можете прочитать об этом в оригинальной статье.

DiffUtil против notifyDataSetChanged ()

Приложение с низкой производительностью и неудовлетворительным пользовательским интерфейсом может расстроить пользователя.

До DiffUtil разработчики Android использовали notifyDataSetChanged () для уведомления RecyclerView, когда список претерпевает изменения. Он сообщает RecyclerView, что весь список потенциально недействителен. В результате RecyclerView повторно рисует и повторно связывает каждый элемент в списке, что может быть очень дорогостоящей операцией.

notifyDataSetChanged () вызывает множество обновлений экрана, что может привести к очень низкой производительности вашего приложения. В крайних случаях это может проявляться в виде мерцания при обновлении экрана и вызывать у пользователей проблемы при прокрутке. Это действительно может расстроить пользователей.

Чтобы решить эту проблему, RecyclerView необходимо точно знать, что изменилось в списке. Благодаря DiffUtil и его способности сравнивать два списка, RecyclerView теперь может перерисовывать только измененные элементы и анимировать эти изменения по умолчанию. Это занимает меньше времени и может значительно повысить производительность приложений Android.

Реализация DiffUtil

  • Создайте тип данных вашего списка. В этом примере используется список, показывающий различные продукты.
  • Создайте собственный класс DiffUtil.Callback, который расширяет класс DiffUtil.Callback. Абстрактный класс DiffUtil.Callback - это класс, который вычисляет разницу между двумя списками. У него пять общедоступных методов:

areContentsTheSame (oldItemPosition: Int, newItemPosition: Int): вызывается DiffUtil, чтобы определить, изменилось ли содержимое элемента. Этот метод проверяет, имеют ли два элемента одинаковые данные. Здесь DiffUtil выполняет обратный вызов, если вы хотите выполнить настраиваемую проверку на равенство. В этом примере используется знак равенства (==) из-за класса данных продукта. Классы данных в Kotlin автоматически определяют метод equals

areItemsTheSame (oldItemPosition: Int, newItemPosition: Int): вызывается DiffUtil, чтобы определить, представляют ли два объекта один и тот же элемент. Другими словами, он вызывается DiffUtil, чтобы проверить, имеют ли два элемента одинаковый идентификатор.

getChangePayload (oldItemPosition: Int, newItemPosition: Int): это вызывается DiffUtil для получения полезной нагрузки об изменении, которое происходит, если areItemsTheSame (oldItemPosition: Int, newItemPosition: Int) возвращает true для двух элементов, а reContentsTheSame (OldItemPosition: Int, newItemPosition: Int) возвращает false.

getNewListSize (): возвращает размер нового списка.

getOldListSize (): возвращает размер старого списка.

  • Создайте собственный класс ListAdapter, который расширяет ListAdapter. Это поможет вам создать адаптер RecyclerView, поддерживаемый списком. ListAdapter помогает адаптеру отслеживать список. ListAdapter имеет два общих элемента (тип данных списка и держатель представления). Зритель принимает DiffItemCallback в качестве параметра конструктора.
  • Уведомлять адаптер об изменениях в списке. Это достигается с помощью метода ListAdapter submitList ().

Заключение

Я надеюсь, что эта статья окажется для вас полезной и что вы начнете использовать DiffUtil в своем RecyclerView для повышения производительности приложения и улучшения взаимодействия с пользователем.