Можете ли вы реализовать свой собственный 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
не может вернуть представление для данной позиции, он выполняет серию шагов для создания нового представления.
Давайте разберем эти шаги:
RecyclerView
после получения отказа отViewCache
попроситеAdapter
вернутьViewType
для данной позиции.- Получив
ViewType
,RecyclerView
проверяет свойRecyclerPool
, чтобы увидеть, присутствует ли кешViewHolder
или нет. - Если
RecyclerPool
проходит, т.е. возвращаетViewHolder
, тоRecyclerView
берет этоViewHolder
вAdapter
и пытаетсяbind
новые данные в него. - После привязки
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
, который вы ищете, не окажется в кеше?
Посмотрим :
- Если
RecyclerPool
не удается, он вернетnull
наRecyclerView
RecyclerView
перейдет кAdapter
и запросит создание новогоViewHolder
изViewType
.Adapter
создаст новыйViewHolder
иbind
сdata
для запрошенногоposition
.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
относятся к абстрактному типу, если вы хотите увидеть, как будет выглядеть их реализация, посмотрите код ниже 👇:
Вывод
Хорошо, дизайн логически кажется правильным до момента, когда рождение держателя вида объясняется в видео.
Надеюсь, вам понравится моя реализация, если вы не предложите улучшения в моем репозитории, где я экспериментирую с кодом:
Во второй части статьи мы продолжим рассмотрение того, как представление менеджера компоновки добавляется в пользовательский интерфейс. Так что следите за обновлениями.
Если вам нравится мой контент и вы хотите увидеть больше, нажмите здесь, чтобы увидеть больше 👇
До следующего раза, удачного взлома! 👨🏻💻
Наслаждайтесь статьей? хлопок очень ценится, если он вам понравился.