Предварительное условие: чтобы получить максимальную отдачу от этой статьи, вы должны быть знакомы с концепцией 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 для повышения производительности приложения и улучшения взаимодействия с пользователем.