Части и функции RecyclerView
RecyclerView
обрабатывает некоторые задачи внутренне (например, прокрутку и перезапуск представлений), но по сути это менеджер, который координирует вспомогательные классы для отображения коллекции. RecyclerView
делегирует задачи следующим вспомогательным классам:
Adapter
— раздувает макеты элементов (создает экземпляр содержимого файла макета) и привязывает данные к представлениям, отображаемым в пределахRecyclerView
. Адаптер также сообщает о событиях щелчка элемента.LayoutManager
— Меры и позиции представлений элементов в пределахRecyclerView
политики для повторного просмотра.ViewHolder
— поиск и хранение ссылок на представление. Владелец представления также помогает обнаруживать щелчки по представлению элементов.ItemDecoration
— Позволяет приложению добавлять специальные смещения рисования и макета в определенные представления для разделителей рисования между элементами, выделениями и границами визуальной группировки.ItemAnimator
— определяет анимации, которые происходят во время действий элемента или при внесении изменений в адаптер.
Связь между RecyclerView
LayoutManager
классами и Adapter
классами показана на следующей схеме:
Как иллюстрирует этот рисунок, LayoutManager
можно рассматривать как посредник между Adapter
и тем RecyclerView
. Вызывает LayoutManager
методы Adapter
от имени RecyclerView
. Например, метод вызывает метод, LayoutManager
когда время создать новое представление для определенной позиции элемента в элементеRecyclerView
.Adapter
Макет Adapter
для этого элемента и создает ViewHolder
экземпляр (не показан), чтобы кэшировать ссылки на представления в этой позиции. LayoutManager
Когда вызывается Adapter
привязка определенного элемента к набору данных, он Adapter
находит данные для этого элемента, извлекает его из набора данных и копирует его в связанное представление элемента.
При использовании RecyclerView
в приложении требуется создание производных типов следующих классов:
RecyclerView.Adapter
— предоставляет привязку из набора данных приложения (который относится к приложению) к представлениям элементов, отображаемым в пределахRecyclerView
. Адаптер знает, как связать каждую позицию представления элемента вRecyclerView
определенном расположении в источнике данных. Кроме того, адаптер обрабатывает макет содержимого в каждом отдельном представлении элемента и создает держатель представления для каждого представления. Адаптер также сообщает события щелчка элемента, обнаруженные представлением элемента.RecyclerView.ViewHolder
— кэширует ссылки на представления в файле макета элемента, чтобы поиски ресурсов не повторялись ненужными. Владелец представления также упорядочивает события щелчка элемента для переадресации в адаптер, когда пользователь нажимает связанное представление элемента владельца представления.RecyclerView.LayoutManager
— позиции в элементеRecyclerView
. Вы можете использовать один из нескольких предопределенных диспетчеров макетов или реализовать собственный пользовательский диспетчер макетов.RecyclerView
делегирует политику макета диспетчеру макетов, поэтому вы можете подключить другой диспетчер макетов без внесения значительных изменений в приложение.
Кроме того, можно дополнительно расширить следующие классы, чтобы изменить внешний вид и ощущение RecyclerView
в приложении:
RecyclerView.ItemDecoration
RecyclerView.ItemAnimator
Если вы не расширяете ItemDecoration
и ItemAnimator
RecyclerView
используете реализации по умолчанию. В этом руководстве не объясняется, как создавать пользовательские ItemDecoration
и ItemAnimator
классы. Дополнительные сведения об этих классах см. в разделе RecyclerView.ItemDecoration и RecyclerView.ItemAnimator.
Как работает рециркуляция представления
RecyclerView
не выделяет представление элементов для каждого элемента в источнике данных. Вместо этого он выделяет только количество представлений элементов, которые помещаются на экране, и он повторно использует эти макеты элементов по мере прокрутки пользователем. Когда представление сначала прокручивается вне видимости, он проходит через процесс переработки, показанный на следующем рисунке:
Когда представление прокручивается вне видимости и больше не отображается, он становится представлением слома.
Представление лома помещается в пул и становится представлением корзины. Этот пул представляет собой кэш представлений, которые отображают одинаковый тип данных.
При отображении нового элемента представление берется из пула перезапуска для повторного использования. Так как это представление должно быть повторно привязано адаптером перед отображением, оно называется грязное представлением.
Представление грязное перезапускается: адаптер находит данные для отображения следующего элемента и копирует эти данные в представления для этого элемента. Ссылки на эти представления извлекаются из владельца представления, связанного с переработанным представлением.
Повторное представление добавляется в список элементов,
RecyclerView
которые собираются перейти на экран.Повторное представление переходит на экран, когда пользователь прокручивает
RecyclerView
следующий элемент в списке. Между тем, другое представление прокручивается вне зрения и перезапускается в соответствии с приведенными выше шагами.
Помимо повторного использования представления элементов, RecyclerView
также используется другая оптимизация эффективности: владельцы представлений. Владелец представления — это простой класс, который кэширует ссылки на представление. Каждый раз, когда адаптер раздувает файл макета элемента, он также создает соответствующий держатель представления. Владелец представления использует для FindViewById
получения ссылок на представления внутри файла макета элемента. Эти ссылки используются для загрузки новых данных в представления при каждом перезапуске макета для отображения новых данных.
Диспетчер макетов
Диспетчер макетов отвечает за размещение элементов в RecyclerView
дисплее; определяет тип презентации (список или сетку), ориентацию (по вертикали или горизонтали) и какие элементы направления должны отображаться (в обычном порядке или в обратном порядке). Диспетчер макетов также отвечает за вычисление размера и положения каждого элемента в отображении RecycleView .
Диспетчер макетов имеет дополнительное назначение: он определяет политику для того, когда перезапускать представления элементов, которые больше не отображаются пользователю. Так как диспетчер макетов знает, какие представления видимы (и которые не являются), лучше всего решить, когда представление может быть переработано. Чтобы перезаработать представление, диспетчер макетов обычно вызывает адаптер для замены содержимого переработанного представления различными данными, как описано ранее в разделе "Как работает перезапуск".
Можно расширить RecyclerView.LayoutManager
создание собственного диспетчера макетов или использовать предварительно определенный диспетчер макетов. RecyclerView
предоставляет следующие предопределенные диспетчеры макетов:
LinearLayoutManager
— упорядочивает элементы в столбце, который можно прокручивать по вертикали или в строке, которую можно прокручивать по горизонтали.GridLayoutManager
— отображает элементы в сетке.StaggeredGridLayoutManager
— отображает элементы в ошеломленной сетке, где некоторые элементы имеют разные высоты и ширины.
Чтобы указать диспетчер макетов, создайте экземпляр выбранного диспетчера макетов и передайте его в SetLayoutManager
метод. Обратите внимание, что по умолчанию диспетчер макетов не выбирает предварительно определенный диспетчер RecyclerView
макетов.
Дополнительные сведения о диспетчере макетов см. в справочнике по классу RecyclerView.LayoutManager.
Держатель представления
Владелец представления — это класс, который определяется для ссылок на кэширование представлений. Адаптер использует эти ссылки на представление для привязки каждого представления к его содержимому. Каждый элемент в элементе RecyclerView
имеет связанный экземпляр владельца представления, который кэширует ссылки на представление для этого элемента. Чтобы создать держатель представления, выполните следующие действия, чтобы определить класс для хранения точного набора представлений для каждого элемента:
- Подкласс
RecyclerView.ViewHolder
. - Реализуйте конструктор, который ищет и сохраняет ссылки на представление.
- Реализуйте свойства, которые адаптер может использовать для доступа к этим ссылкам.
Подробный ViewHolder
пример реализации представлен в примере Basic RecyclerView.
Дополнительные сведения смRecyclerView.ViewHolder
. в справочнике по классу RecyclerView.ViewHolder.
Адаптер
Большая часть кода интеграции выполняется RecyclerView
в адаптере. RecyclerView
требуется предоставить адаптер, производный от RecyclerView.Adapter
доступа к источнику данных, и заполнить каждый элемент с содержимым из источника данных.
Так как источник данных зависит от приложения, необходимо реализовать функциональные возможности адаптера, которые понимают, как получить доступ к данным. Адаптер извлекает сведения из источника данных и загружает его в каждый элемент коллекции RecyclerView
.
На следующем рисунке показано, как адаптер сопоставляет содержимое в источнике данных с помощью держателей представлений с отдельными представлениями в каждом элементе RecyclerView
строки в следующем:
Адаптер загружает каждую RecyclerView
строку с данными для определенного элемента строки. Например, для положения строки P адаптер находит связанные данные в позиции P в источнике данных и копирует эти данные в элемент строки в позиции P в RecyclerView
коллекции.
Например, в приведенном выше рисунке адаптер использует держатель представления для поиска ссылок на ImageView
эту позицию, TextView
поэтому пользователю не нужно повторно вызывать FindViewById
эти представления, так как пользователь прокручивает коллекцию и повторно использует представления.
При реализации адаптера необходимо переопределить следующие RecyclerView.Adapter
методы:
OnCreateViewHolder
— создает экземпляр файла макета элемента и держателя представлений.OnBindViewHolder
— загружает данные по указанной позиции в представления, ссылки которых хранятся в заданном держателе представления.ItemCount
— возвращает количество элементов в источнике данных.
Диспетчер макетов вызывает эти методы во время размещения элементов внутри RecyclerView
.
Уведомление о изменениях в корзине данных
RecyclerView
не обновляется автоматически при изменении содержимого источника данных; Адаптер должен уведомить RecyclerView
об изменении набора данных. Набор данных может изменяться различными способами; Например, содержимое элемента может измениться или общая структура данных может быть изменена.
RecyclerView.Adapter
предоставляет ряд методов, которые можно вызывать таким образом, чтобы RecyclerView
реагировать на изменения данных наиболее эффективно:
NotifyItemChanged
— сигнализирует об изменении элемента в указанной позиции.NotifyItemRangeChanged
— сигналы о том, что элементы в указанном диапазоне позиций изменились.NotifyItemInserted
— сигнализирует о том, что элемент в указанной позиции был добавлен.NotifyItemRangeInserted
— сигнализирует о том, что элементы в указанном диапазоне позиций были вставлены.NotifyItemRemoved
— сигнализирует о том, что элемент в указанной позиции удален.NotifyItemRangeRemoved
— сигнализирует о том, что элементы в указанном диапазоне позиций были удалены.NotifyDataSetChanged
— сигнализирует об изменении набора данных (принудительное полное обновление).
Если вы точно знаете, как изменился набор данных, можно вызвать соответствующие методы, описанные выше, чтобы обновить RecyclerView
их наиболее эффективно. Если вы не знаете точно, как изменился набор данных, можно вызвать NotifyDataSetChanged
, что гораздо менее эффективно, так как RecyclerView
необходимо обновить все представления, видимые пользователю. Дополнительные сведения об этих методах см. в разделе RecyclerView.Adapter.
В следующем разделе приведен пример приложения Basic RecyclerView, демонстрирующий реальные примеры кода частей и функциональных возможностей, описанных выше.