«Оживляем» Android-приложение. Часть 1. RecyclerView.

«Оживляем» Android-приложение. Часть 1. RecyclerView.

Android Live

Это будет первая статья из цикла про «оживление» Android-приложений. Тут я хочу собрать всю информацию, которая связана с анимациями. Мне хочется сделать обзор всех (ну или большинства) способов создания красивых экранов, плавных переходов и прочего. Здесь будут обзоры библиотек, подходов, а также советы. На мой взгляд, большинство этих советов будут полезны начинающим разработчикам.

Сегодня достаточно сложно найти хорошее приложение без анимаций.

Анимации делают пользование приложением более приятным, а также помогают скрыть некоторые технические нюансы.

Главным элементом для вывода списков является элемент RecyclerView. В 90% случаях, данные для списка приходят с сервера. При этом, данные устаревают и их нужно обновлять. Иногда достаточно актуализировать их при заходе на экран, в другой же раз нужно делать это с некоторой периодичностью.


notifyDataSetChanged()

Для того, чтобы обновить данные, нужно сделать notifyDataSetChanged() в Adapter:

public void update(List<Item> newItems) {
    this.items.clear();
    this.items.addAll(newItems);
    notifyDataSetChanged();
}

При этом список никак не будет анимироваться. Такой способ подходит в случае полного изменения списка, он достаточно затратен. Документация говорит о том, что такой метод лучше использовать «в случае крайней необходимости». Взамен, предлагается использовать целый набор других способов.


notifyItemChanged(int)...

Это уже более специфичные методы для обновления списка. Их есть целый набор, специфичный для конкретной задачи.

Рассматривая метод notifyItemChanged(int), мы получаем обновление элемента в переданной позиции.

При этом применяется стандарт SimpleItemAnimator, который позволяет анимировать элементы списка. Можно также задать кастомный Animator.


DiffUtil

В 24.2.0 версии RecyclerView, Google добавили удобный способ для обновления списков. При этом используется алгоритм Юджина Майерса для подсчета разницы между элементами.

Чтобы использовать данный метод, нужно переопределить DiffUtil.Callback, который имеет следующие методы:

  • getOldListSize() — размер старого списка;
  • getNewListSize() — размер нового списка;
  • areItemsTheSame(int old, int newPos) — определяет, по какому признаку два элемента одинаковые;
  • areContentsTheSame(int oldPos, int newPos) — определяет, по какому признаку контент в элементах одинаковый. Он вызывается, если areItemsTheSame() возвращает true.
  • getChangePayload(int oldPos, int newPos) — метод, позволяющий переопределить стандартный Payload. Вызывается, если areItemTheSame() возвращает true и areContentsTheSame() возвращает false. При этом, можно переопределить стандартный ItemAnimator.

Информацию о производительности можно найти в доке.

Важно помнить, что если ваш список содержит огромное количество элементов, то на подсчет разницы может уйти достаточно большое время. Лучше всего запускать операцию в отдельном потоке, потом передавать результат в main.

Подобный способ очень хорошо показывает себя на экранах поиска.


Это те способы обновления списков, которыми я хотел поделиться сегодня. Если вам есть что добавить, то пишите мне.

Подписывайтесь на канал @android_live.


Источники:

1) Smart way to update RecyclerView using DiffUtil
2) How to revitalize an Android app without bloating the budget

Report Page