Можете ли вы реализовать свой собственный RecyclerView с нуля? Вы больше никогда не откажетесь.

официально опубликовано:



‌Представлен на:



Все мы давно работали с RecyclerViews и хорошо знакомы с его API для эффективного отображения нашего списка, но многие только коснулись его поверхности на очень высоком уровне, немногие из нас глубоко вникли в него и пытались понять, как внутри оно работает. Я один из тех же, у меня есть общее представление о том, что может происходить, но я никогда не смотрел на его реализацию из проекта с открытым исходным кодом Android (AOSP), но прежде чем я это сделаю, я хотел выяснить, как другие в сообществе исследовали Это.

После некоторого осмотра многие разработчики посоветовали мне следить за докладом на тему Входы и выходы RecyclerViews - Google I / O 2016, чтобы получить представление о том, что RecyclerViews делают в капот. Если вы еще не видели его, я настоятельно рекомендую вам посмотреть это видео, на самом деле добавьте его в закладки, вы будете часто посещать его в своей карьере Android.

«На самом деле он довольно неплохо объясняет различные компоненты RecyclerView, и эти диаграммы являются». Но это также проблема с видео, хотя в видео очень много деталей, но все просто в форме диаграмм и потоков. Мы не видим никаких примеров кода или реализаций, которые могли бы помочь нам глубже понять точку зрения Recycler.

Поскольку этого не сделано, и я не хочу ранить свою душу, заглядывая в AOSP, я решил использовать свой большой 🧠, чтобы воплотить эти диаграммы в работоспособный код.

Это видео разделено на 4 части:

  • Рождение ViewHolder
  • Добавление представления в пользовательский интерфейс
  • Смерть ViewHolder
  • Анимация на RecyclerView Операции

Судя по названию статьи, вы, должно быть, догадались, что я расскажу о первом разделе, то есть о рождении ViewHolder, а затем давайте рассмотрим RecyclerView Компоненты.

Компоненты RecycleView

Первая половина видео познакомила нас с различными компонентами RecyclerView. Давайте сделаем наши классы соответственно этому.

p.s. В комментариях я добавил обязанности каждого компонента.

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

  • Связывание данных,
  • Уведомлять об изменении данных,
  • Повторное восстановление,
  • Работа с несколькими типами представлений и др.

Приступим к реализации

Рождение держателя взгляда

При создании ViewHolder встречаются три возможных сценария.

  • Просмотр успешного кеширования
  • Просмотр сбой кеша, успешный пул ресайклера
  • Просмотр сбоев кеша и сбоев пула ресайклера

‌ Просмотр успешного кеширования ✅

В первом разделе мы узнаем, что LayoutManager запрашивает RecyclerView просмотр позиции. Recycler - очень быстрый компонент, потому что он пытается кэшировать данные на каждом этапе.

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

Сценарий, в котором Recycler View Cache Pass, т.е. он возвращает кэшированный View экземпляр, немедленно удовлетворяя запрос менеджера компоновки.

Первый вариант использования потока приводит к следующему взаимодействию компонентов, ‌

Component interactions :
    [Layout Manager] ---- getViewForPosition ----> [Recycler View]
    [Recycler View] ---- getViewForPosition ----> [View Cache]
    [View Cache] ---- cache returns View ✅ ----> [Recycler View]
    [Recycler View] ---- returns View ----> [Layout Manager]

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

‌В программе это означает: ‌

Если вы не знаете, что TODO(), посмотрите мою статью здесь:



View Cache Failed ❌, Recycler Pool Success

Когда View Cache не может вернуть представление для данной позиции, он выполняет серию шагов для создания нового представления.

Давайте разберем эти шаги:

  1. RecyclerView после получения отказа от ViewCache попросите Adapter вернуть ViewType для данной позиции.
  2. Получив ViewType, RecyclerView проверяет свой RecyclerPool, чтобы увидеть, присутствует ли кеш ViewHolder или нет.
  3. Если RecyclerPool проходит, т.е. возвращает ViewHolder, то RecyclerView берет это ViewHolder в Adapter и пытается bind новые данные в него.
  4. После привязки RecyclerView берет View ViewHolder и возвращает его Layout Manager.

Сказал, что создание представления - дорогостоящая задача. Давайте посмотрим на взаимодействие компонентов в этом процессе: ‌

Component interactions :
    [Layout Manager] ---- getViewForPosition ----> [Recycler View]
    [Recycler View] ---- getViewForPosition ----> [View Cache]
    [View Cache] ---- cache returns null ❌ ----> [Recycler View]
    [Recycler View] ---- getViewType ----> [Adapter]
    [Adapter] ---- ViewType ----> [Recycler View]
    [Recycler View] ---- getViewHolderByType ----> [RecyclerPool]
    [RecyclerPool] ---- ViewHolder ----> [Recycler View]
    [Recycler View] ---- bindViewHolder ----> [Adapter]
    [Adapter] ---- View ----> [Recycler View]
    [Recycler View] ---- View ----> [Layout Manager]

‌Вы можете следить за последовательностью, чтобы увидеть поток управления: ‌

‌В программе это означает: ‌

ИМО, API получается красиво оформленным, просто следуя диаграммам в видео.

Не удалось просмотреть кэш ❌, сбой пула ресайклера ❌

RecyclerPool - это кеш Viewholders, что произойдет, если Viewholder, который вы ищете, не окажется в кеше?

Посмотрим :

  1. Если RecyclerPool не удается, он вернет null на RecyclerView
  2. RecyclerView перейдет к Adapter и запросит создание нового ViewHolder из ViewType.
  3. Adapter создаст новый ViewHolder и bind с data для запрошенного position.
  4. Adapter вернет ViewHolder в RecyclerView, а RecyclerView вернет View обратно в LayoutManger.

Таким образом, только один шаг является дополнительным, когда RecyclerPool выходит из строя, Adapter создаст новые Viewholder и binds данные.

Посмотрим на взаимодействие компонентов: ‌

Component interactions :
    [Layout Manager] ---- getViewForPosition ----> [Recycler View]
    [Recycler View] ---- getViewForPosition ----> [View Cache]
    [View Cache] ---- cache returns null ❌ ----> [Recycler View]
    [Recycler View] ---- getViewType ----> [Adapter]
    [Adapter] ---- ViewType ----> [Recycler View]
    [Recycler View] ---- getViewHolderByType ----> [Recycler Pool]
    [Recycler Pool] ---- returns ViewHolder ❌ ----> [Recycler View]
    [Recycler View] ---- createViewHolder ----> [Adapter]
    [Adapter] ---- bindViewHolder ----> [Adapter]
    [Adapter] ---- ViewHolder ----> [Recycler View]
    [Recycler View] ---- View ----> [Layout Manager]

‌Следуйте последовательности операций управления: ‌

‌‌В программе это означает: ‌

Adapter и ViewHolder относятся к абстрактному типу, если вы хотите увидеть, как будет выглядеть их реализация, посмотрите код ниже 👇: ‌

Вывод

Хорошо, дизайн логически кажется правильным до момента, когда рождение держателя вида объясняется в видео.

Надеюсь, вам понравится моя реализация, если вы не предложите улучшения в моем репозитории, где я экспериментирую с кодом:



Во второй части статьи мы продолжим рассмотрение того, как представление менеджера компоновки добавляется в пользовательский интерфейс. Так что следите за обновлениями.

Если вам нравится мой контент и вы хотите увидеть больше, нажмите здесь, чтобы увидеть больше 👇

https://chetangupta.net/

До следующего раза, удачного взлома! 👨🏻‍💻

‌Наслаждайтесь статьей? хлопок очень ценится, если он вам понравился.