Что такое recyclerview android studio

Реализация списка с заголовком, футером и пагинацией в Андроид

RecyclerView

RecyclerView — это расширенная версия ListView с некоторыми улучшениями в производительности и с новыми функциями. Как следует из названия, RecyclerView перерабатывает или повторно использует представления элементов при прокрутке. В RecyclerView гораздо проще добавлять анимации по сравнению с ListView. В этом уроке мы разберем, как создать RecyclerView с заголовком, футером, разбиением на страницы и анимацией.

Настройка Gradle

Добавьте следующую зависимость в файл build.gradle:

Добавление RecyclerView в XML представление

После того, как проект будет синхронизирован, добавьте компонент RecyclerView в ваш макет:

Привязка XML с классом JAVA

Теперь в методе onCreate вашей активности добавьте следующий код:

Прежде чем идти дальше, давайте подробно рассмотрим приведенный выше код

  • Layout Manager — Простыми словами, Layout Manager помогает нам определить структуру нашего RecyclerView. Есть три встроенных Layout Managers. Помимо этого, мы можем создать собственный пользовательский Layout Manager, чтобы удовлетворить наши требования.

  1. LinearLayoutManager показывает элементы в списке с вертикальной или горизонтальной прокруткой.
  2. GridLayoutManager показывает элементы в сетке.
  3. StaggeredGridLayoutManager показывает элементы в шахматной сетке.

RecyclerView ItemDecoration

ItemDecoration позволяет приложению добавлять специальный полосы и смещения к определенным представлениям элементов из набора данных адаптера. Это может быть полезно для рисования разделителей между элементами, выделениями, границами визуальной группировки и т. д. – developer.android.com

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

В вышеприведенном классе мы устанавливаем отступы к нулевому элементу.

RecyclerView Adapter

Теперь давайте настроим адаптер ReeyclerView с заголовком и футером.

Пагинация

Теперь, когда адаптер готов, давайте посмотрим, как добавить пагинацию в список RecyclerView. Это довольно легко сделать и должно быть добавлено в onCreate после установки Adapter to Recycler-View.

Всякий раз, когда данные изменяются в mList, вызывайте функцию ниже, чтобы обновить адаптер RecyclerView и показать новые данные.

Надеюсь, что этот пост поможет вам получить общее представление о настройке RecyclerView с заголовком, подвалом и пагинацией.

Источник

RecyclerView

RecyclerView — компонент для отображения элементов списка, который является более продвинутой и гибкой версией ListView , но не является его родственником, а относится к семейству ViewGroup .

Принцип работы

Для отображения данных RecyclerView использует несколько компонентов:

  • Объект RecyclerView , который нужно добавить в макет. Он заполняется элементами списка в зависимости от того, какой был установлен LayoutManager . Существуют стандартные LayoutManager ‘ы, например, LinearLayoutManager отображает элементы в виде списка, а GridLayoutManager — в виде сетки. Но можно создать и свой собственный LayoutManager .
  • Элементы списка представлены в виде объектов viewHolder . Например, если список состоит из различных видов деревьев, то viewHolder — это конкретный вид дерева — сосна, яблоня, берёза и т.д. RecyclerView создает столько объектов viewHolder , сколько требуется для отображения на экране устройства и несколько про запас. Когда пользователь начинает прокручивать список, RecyclerView берёт те объекты viewHolder , которые ушли за пределы экрана и “привязывает” к ним новые данные.
  • Объекты viewHolder управляются адаптером. Он создаёт объекты viewHolder и привязывает к ним информацию.

Добавление RecyclerView в проект

Библиотека

По умолчанию (при создании нового проекта) функциональность RecyclerView не доступна. Поэтому для начала нужно добавить соответствующую библиотеку. Для этого в файл build.gradle , который находится в папке app , добавьте одну из библиотек:

Версия support library уже вряд ли когда-нибудь изменится, так как её поддержку остановили. А вот за версией androidx нужно следить.

После того, как библиотека добавлена, обязательно нажмите на кнопку Sync Now, чтобы изменения вступили в силу.

Добавление в макет

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

Либо может быть единственным (корневым) компонентом макета:

Далее для корректной работы RecyclerView требуется установить LayoutManager и адаптер. LayoutManager может быть установлен двумя способами. В макете:

Либо вместе с адаптером в классе фрагмента или активити:

При этом начиная с версии Android Studio 3.6 необязательно вызывать метод findViewById(), а можно напрямую обратится к компоненту из макета по его идентификатору (как в примере выше).

Макет элемента списка

Для элемента списка можно создать собственный макет. Например, у меня каждый элемент состоит из названия дерева и его краткого описания. Поэтому макет для элемента включает в себя два компонента TextView :

Читайте также:  Summertime saga вылетает андроид

А можно воспользоваться стандартными макетами, к которым можно обращаться через android.R.layout.НАЗВАНИЕ_ИЗ_СПИСКА . Но на мой взгляд это вариант для ленивых или для любопытных.

Адаптер и viewHolder

Адаптер — это класс, который занимается передачей данных в список, созданием объектов viewHolder и их обновлением. Адаптер должен наследоваться от класса RecyclerView.Adapter .

ViewHolder — это тоже класс, объекты которого адаптер использует для хранения и визуализации элементов списка. ViewHolder должен наследоваться от класса RecyclerView.ViewHolder . Как правило этот класс располагают внутри адаптера.

В классе адаптера нужно обязательно переопределить 3 метода:

  • onCreateViewHolder() — данный метод вызывается LayoutManager ‘ом, чтобы создать объекты viewHolder и передать им макет, по которому будут отображаться элементы списка.
  • onBindViewHolder() — данный метод вызывается LayoutManager ‘ом, чтобы привязать к объекту viewHolder данные, которые он должен отображать.
  • getItemCount() — возвращает общее количество элементов в списке.

А в классе ViewHolder требуется указать используемые компоненты разметки.

Последние штрихи

Теперь адаптер настроен и готов к использованию. Осталось только его подключить. Делается это в классе фрагмента или активити (в моём примере используется фрагмент).

Если какой-либо элемент списка изменился, то следует вызвать метод адаптера notifyItemChanged() и передать ему позицию элемента, которую требуется обновить. Вместо него можно использовать метод notifyDataSetChanged() , который будет обновлять полностью весь список, но из-за этого он является ресурсозатратным.

Создание RecyclerView с помощью шаблона

Есть возможность пропустить все вышеописанные шаги и воспользоваться стандартным шаблоном. Этот шаблон автоматически добавит в проект новый фрагмент с поддержкой RecyclerView . Это означает, что студия за вас создаст не только фрагмент, но и адаптер, ViewHolder , макет для элемента списка, а также код, который всё это подключает.

Кликните по любому файлу правой кнопкой мыши и в появившемся контекстном меню выберите: New > Fragment > Fragment (List).

Стандартные LayoutManager’ы

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

Существует три стандартных LayoutManager ‘а:

  • LinearLayoutManager — упорядочивает элементы в виде обычного вертикального или горизонтального списка.
  • GridLayoutManager — размещает элементы в виде сетки одинакового размера.
  • StaggeredGridLayoutManager — размещает элементы в виде неравномерной сетки: каждый столбец будет слегка смещён по сравнению с предыдущим.

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

LinearLayoutManager

По умолчанию LinearLayoutManager упорядочивает элементы в виде вертикального списка.

У данного класса есть другой конструктор, который позволяет явно задать ориентацию списка. Помимо контекста, ему требуется два параметра:

  • Ориентация — задаётся с помощью констант HORIZONTAL и VERTICAL класса LinearLayoutManager .
  • Булево значение: если передать true — список будет установлен в обратном порядке (начало будет в конце).

Эти параметры можно устанавливать с помощью специальных методов:

Либо с помощью специальных атрибутов в XML:

GridLayoutManager

Размещает элементы списка в виде сетки одинакового размера.

У класса GridLayoutManager есть два конструктора. Для использования первого конструктора необходимы два параметра: контекст и количество столбцов в сетке.

Для второго конструктора — четыре параметра:

  • контекст;
  • количество столбцов в сетке;
  • ориентация списка — задаётся с помощью констант HORIZONTAL и VERTICAL класса LinearLayoutManager ;
  • булево значение — если передать true — список будет установлен в обратном порядке (начало будет в конце).

Если задать горизонтальную ориентацию, то в списке будет столько рядов, сколько было задано вторым параметром (в данном примере = 3), а листаться, само собой, будет в бок.

То же самое можно задать с помощью XML атрибутов:

StaggeredGridLayoutManager

Размещает элементы в виде неравномерной сетки.

У класса StaggeredGridLayoutManager всего один конструктор с двумя параметрами:

  • количество столбцов в сетке;
  • ориентация списка — задаётся с помощью констант HORIZONTAL и VERTICAL класса StaggeredGridLayoutManager .

Если задать горизонтальную ориентацию, то в списке будет столько рядов, сколько было задано первым параметром (в данном примере = 3), а листаться, само собой, будет в бок.

То же самое можно задать с помощью XML атрибутов:

Динамическое переключение

Переключаться между LayoutManager ‘ами можно динамически. Например, при нажатии на кнопку:

SnapHelper

SnapHelper позволяет настроить “прилипание” элементов к определённой позиции в RecyclerView . Например, при пролистывании можно настроить прилипание таким образом, что первый видимый элемент будет сам прилипать к краю экрана или ближайший к центру элемент будет автоматически вставать в центр экрана.

Существует два стандартных класса для работы с прилипанием элементов: LinearSnapHelper и PagerSnapHelper .

LinearSnapHelper застовляет ближайший к центру элемент вставать в центр экрана. Допустим вы листаете список и в какой-то момент убрали пальцы от экрана. Список без вашего участия автоматически прокрутится и установит в центр экрана ближайший элемент.

Читайте также:  Android getsupportactionbar in fragment

PagerSnapHelper предназначен для полноэкранных элементов и ведёт себя как ViewPager .

Добавить себе в проект просто:

Если ни один вариант вас не устраивает, то создайте свою собственную реализацию этих классов и опишите в нёй необходимое поведение элементов при пролистывании списка.

Использование нескольких макетов для элементов RecyclerView

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

  • требуется добавить header или footer;
  • отображение двух списков в одном RecyclerView ;
  • выделение определённого элемента в списке.

ViewType

Одним из способов, который используется для выделения элементов в списке, является присвоение viewType каждому объекту viewHolder . ViewType — это произвольное цифровое значение от 0 и выше, которое необходимо для того, чтобы различать объекты viewHolder между собой. Например, если вам требуется добавить header и footer, при этом элементы списка должны выглядеть идентично, то у вас будет три viewType : для header’а, footer’а и элемента списка.

Для начала добавьте в папку res/layout три макета: для header’а, footer’а и элемента списка.

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

Для удобства создадим базовый класс GenericViewHolder .

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

Обратите внимание на класс ListItemViewHolder . В отличии от остальных он является внутренним (модификатор inner ), так как ему для привязки данных требуется обращаться к свойству trees своего внешнего класса. Из поступившего номера позиции вычитается единица, так как нулевая позиция занята header’ом и не будет сюда поступать.

Теперь возьмёмся за код самого адаптера. С помощью метода getItemViewType() зададим viewType каждому объекту viewHolder в зависимости от его позиции в списке. Первый и последний элемент списка — это header и footer. Если в списке 15 элементов, то позиция для footer’а будет 15 + 1, так как header всегда находится в нулевой позиции.

В методе onCreateViewHolder() создаём объект viewHolder в зависимости от viewType .

В методе onBindViewHolder() вызываем метод привязки данных bindView() , который переопределён во всех наших классах ViewHolder .

Метод getItemCount() должен возвращать количество элементов в RecyclerView . Поэтому следует учесть наличие header’а и footer’а.

Адаптер готов к использованию. Результат будет примерно таким:

Несколько списков в одном RecyclerView

У меня как-то возникала необходимость отображения двух списков на одном экране друг за другом. При этом при клике по элементу из первого списка он должен был переместиться во второй список и наоборот.

Первая появившаяся мысль — добавить на экран два RecyclerView . И это вполне себе работает. Но возникает ряд неудобств, одно из них — некорректная работа overScroll. Эффект overScroll визуально показывает, что вы дошли до конца или начала списка.

И если на экране два RecyclerView , то эффект overScroll появляется для каждого из них. Выглядит не очень красиво. Конечно можно overScroll эффект отключить, но тогда появляется неуверенность: “А дошел ли я до конца списка?”.

В общем нашлось решение, при котором один RecyclerView работает с двумя списками и завязано это всё на использовании viewType из примера выше.

Создаём два макета — один для элементов первого списка, второй — для элементов второго списка. У меня они отличаются только цветом фона — у элементов первого списка он белый, у второго — красный.

Константы для хранения значений viewType :

Также используем для удобства базовый класс GenericViewHolder .

От него будут наследоваться два класса ViewHolder : один для элементов первого списка, второй для элементов второго списка.

Каждый из них будет по своему реализовывать метод bindView() . Для элементов первого списка ничего рассчитывать не требуется, нужно просто привязать к объектам viewHolder данные по порядку.

Второй список должен отображаться сразу после первого. Так как номер позиции может быть любым числом от 0 до list1.size + list2.size , в методе bindView() класса SecondListItemViewHolder потребуется произвести расчеты.

Также обратите внимание что оба класса являются внутренними (модификатор inner ), так как им для привязки данных требуется обращаться к компонентам адаптера list1 и list2 .

Переходим к коду адаптера. В методе getItemViewType() нужно предусмотреть все возможные сценарии: когда в обоих списках есть элементы и когда в одном из списков нет элементов.

В методе onCreateViewHolder() создаём объект viewHolder в зависимости от viewType .

В методе onBindViewHolder() вызываем метод привязки данных bindView() , который переопределён во всех наших классах ViewHolder , а также вешаем слушателя.

Метод getItemCount() должен возвращать количество элементов в RecyclerView . Поэтому следует учесть наличие двух списков.

При клике по элементу из первого или второго списка будет вызван метод updateUi() , который отмечает, что по элементу кликнули и переносит его в другой список.

Читайте также:  Андроид навигатор как закачать карты

Адаптер готов к использованию. Результат будет примерно таким:

Необязательно делать списки динамическими, таким образом можно отображать и статические списки. И даже комбинировать с предыдущим примером — добавлять header (один или для всех списков) и footer.

ConcatAdapter

Несмотря на то, что все примеры, описанные в предыдущем разделе, вполне себе рабочие, в плане кода выглядят не очень хорошо. В основном из-за того, что в одном адаптере скапливается множество реализаций класса ViewHolder , а также логика их отображения. Если нам понадобится добавить или удалить какой-либо ViewHolder , то придётся переписывать класс адаптера и заново его тестировать.

По этой причине в recyclerview:1.2.0-alpha02 был добавлен новый класс MergeAdapter , который в версии recyclerview:1.2.0-alpha04 переименовали в ConcatAdapter .

ConcatAdapter позволяет отображать содержимое нескольких адаптеров в одном RecyclerView . То есть вместо накапливания множества реализаций класса ViewHolder в одном адаптере, мы можем создать для каждого ViewHolder ‘а свой адаптер, а потом объединить их все при помощи ConcatAdapter . Таким образом код станет более понятным и переиспользуемым, а если потребуется добавить в RecyclerView что-то новое — просто создадим новый адаптер.

Использование ConcatAdapter . Обзор некоторых методов класса

Передайте в конструктор ConcatAdapter все ваши адаптеры, которые нужно объединить, чтобы отображать их в одном RecyclerView .

Адаптеры будут отображаться на экране в том порядке, в котором были переданы в конструктор класса ConcatAdapter .

Если один из адаптеров должен несколько раз отображаться на экране, то создайте несколько объектов этого адаптера и передайте их все в конструктор класса ConcatAdapter .

Когда мы вызываем метод notifyDataSetChanged() в любом из адаптеров, ConcatAdapter тоже его вызывает.

У класса ConcatAdapter есть конструктор, который позволяет передавать список из адаптеров. На экране они будут отображаться в том порядке, в котором были добавлены в список.

Если вам нужно добавить один из адаптеров не сразу, а позже, то используйте метод addAdapter() . Этот метод добавляет адаптер в последнюю позицию, т.е. отображаться он будет после всех остальных.

Если же требуется добавить адаптер не последним, а в определённую позицию, то в метод addAdapter() передайте номер позиции и сам адаптер. Метод добавит адаптер в указанную позицию, а все остальные адаптеры сместятся.

Обратите внимание, что номер позиции не может быть больше количества адаптеров (отсчёт начинается с нуля). В примере у нас три адаптера, каждому из которых может быть присвоена позиция 0, 1 или 2. Если указать число выше, то вылетит ошибка.

Для удаления адаптера используется метод removeAdapter() .

Чтобы узнать сколько элементов объединил в себе ConcatAdapter вызовите метод itemCount . Количество элементов суммируется со всех добавленных адаптеров.

Можно получить список всех адаптеров, добавленных в ConcatAdapter . Для этого вызовите adapters , который возвращает MutableList со всеми адаптерами.

Обычно если в адаптере нам надо обратиться к какой-либо позиции, мы используем метод getAdapterPosition() класса ViewHolder . При работе с ConcatAdapter вместо getAdapterPosition() следует использовать getBindingAdapterPosition() .

Возьмём пример, который был в разделе ViewType: требуется отобразить header, footer и список между ними. В таком случае у нас будет три адаптера: для header’а, footer’а и элементов списка. Можно использовать и два адаптера, если логика и внешний вид header’а и footer’а идентичны. Но для наглядности в своём примере я буду использовать три.

Для начала убедитесь, что в build.gradle добавлена нужная версия библиотеки recyclerView:

Можно использовать и версию 1.2.0-alpha02 , но учтите, что в этой версии ConcatAdapter ещё носит название MergeAdapter .

Создадим классы данных для header’а, footer’а и элементов списка (деревья).

Добавим макет для каждого компонента.

За отображение header’а будет отвечать HeaderAdapter .

Для отображения элементов списка создадим ListItemAdapter .

Ну и наконец адаптер для отображения footer’а.

Теперь осталось лишь объединить всё вместе в методе onCreate() — для активити или в методе onViewCreated() — для фрагмента. Для этого создадим по одному объекту каждого из адаптеров и передадим их классу ConcatAdapter() в том порядке, в котором они должны быть отражены на экране.

Если же в ConcatAdapter() передать footer сразу после header’а

то результат будет таким:

Полезные ссылки

Общие ссылки по теме:
Create a List with RecyclerView — гайд из официальной документации.
RecyclerView — документация по классу (androidx).
Recyclerview — Release Notes — информация о выходе новых версий.
Using the RecyclerView — гайд от codepath.

Кастомизация:
Having multiple lists in a single RecyclerView — гайд по использованию нескольких списков в одном RecyclerView .

Адаптеры:
ConcatAdapter — официальная документация.

Код:
RecyclerView — полный код всех примеров из данной статьи.
MergeAdapter-sample — пример реализации ConcatAdapter от Kotlin Android Open Source.
Concat Adapter Android Example — пример реализации ConcatAdapter от Mindorks.

Источник

Оцените статью