Android studio recyclerview заголовок

Содержание
  1. Get ahead using headers in RecyclerView
  2. Create header layout
  3. Creating HeaderAdapter and HeaderViewHolder
  4. Using ConcatAdapter in the Activity class
  5. Next Steps
  6. Реализация списка с заголовком, футером и пагинацией в Андроид
  7. RecyclerView
  8. Настройка Gradle
  9. Добавление RecyclerView в XML представление
  10. Привязка XML с классом JAVA
  11. RecyclerView ItemDecoration
  12. RecyclerView Adapter
  13. Пагинация
  14. Создание сложного RecyclerView за 20 минут в Android на базе Groupie
  15. Создание проекта и добавление библиотек.
  16. Создание ячеек для отображения контента
  17. Создание главной ячейки с вложенным RecyclerView
  18. Ячейка для фильма
  19. Квадратная ячейка для отображения обложки игры
  20. Все вместе. Соединяем все ячейки вместе
  21. RecyclerView
  22. Принцип работы
  23. Добавление RecyclerView в проект
  24. Библиотека
  25. Добавление в макет
  26. Макет элемента списка
  27. Адаптер и viewHolder
  28. Последние штрихи
  29. Создание RecyclerView с помощью шаблона
  30. Стандартные LayoutManager’ы
  31. LinearLayoutManager
  32. GridLayoutManager
  33. StaggeredGridLayoutManager
  34. Динамическое переключение
  35. SnapHelper
  36. Использование нескольких макетов для элементов RecyclerView
  37. ViewType
  38. Несколько списков в одном RecyclerView
  39. ConcatAdapter
  40. Использование ConcatAdapter . Обзор некоторых методов класса
  41. Пример с header’ом и footer’ом
  42. Полезные ссылки

Get ahead using headers in RecyclerView

This is the fourth in a series of articles which cover the fundamentals of using RecyclerView . If you already have a solid understanding of how to create a RecyclerView , then carry on. Otherwise, consider starting with this post.

You can add information and context about your app’s data by including a Header in your RecyclerView . Although you can emulate a header by placing a TextView above your RecyclerView in a LinearLayout , this fake header stays on screen even when a user scrolls toward the bottom of the RecyclerView . By providing a genuine header element, you allow the header to scroll off screen when the user scrolls through a RecyclerView .

This blog post goes through adding a Header to a RecyclerView that displays different types of flowers. The Header displays the text “Flower Finder” and displays the number of flowers in the list.

Create header layout

Create a layout file which defines what the Header looks like.

Creating HeaderAdapter and HeaderViewHolder

Create a new file to request and bind the Header’s view.

The Adapter for the Header inherits from RecyclerView.Adapter () .

Inside of the Header’s Adapter , create a ViewHolder that inherits from RecyclerView.ViewHolder . If you have dynamic text, create a val to represent the TextView that will be updated. Create a bind() function that updates the TextView to the value passed in.

In the class definition, update the Adapter’s parameter to take in HeaderViewHolder .

Since the Adapter inherits from RecyclerView.Adapter , it has to implement onCreateViewHolder() , onBindViewHolder() and getItemCount() .

  • onCreateViewHolder() inflates the view and returns a HeaderViewHolder .
  • getItemCount() returns 1 since there is only one Header item.
  • onBindViewHolder() binds information to the Header .

Using ConcatAdapter in the Activity class

In the Activity class, create a val to hold the HeaderAdapter() above the RecyclerView’s Adapter .

Then use the ConcatAdapter to add both of the adapters to the RecyclerView . ConcatAdapter presents the contents of multiple adapters sequentially. Add in headerAdapter before flowersAdapter .

Run the code and voila! It’s that easy to add a Header .

Next Steps

The full code sample including Header can be found here.

Thank you for reading the last installment in my RecyclerView series, if you missed the other posts check them out here!

Источник

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

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 за 20 минут в Android на базе Groupie

Списки являются основным способом представления различного контента в мобильных приложениях. Будь то социальная сеть, приложение для чтения книг или интернет-магазин, в большинстве таких приложений встречаются списки с разными видами ячеек, разного уровня вложенности.

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

Итак, задача: создать список для отображения различного вида контента, при этом каждая категория, то есть ячейка списка может содержать неограниченное количество более мелких ячеек и иметь горизонтальный скрол. Звучит сложно? Если вы думаете что это сложная задача, над которой вам нужно будет работать всю неделю, то спешу вас обрадовать, мы сделаем такой список примерно на полчаса.

Подходов к решению такой задачи, множество, но суть решения одна — здесь необходимо использовать RecyclerView с различными типами ячеек, в которых также находится RecyclerView для возможности горизонтального скролла неограниченного количества ячеек. Можно использовать как стандартный подход, в котором необходимо будет создать adapter для каждого из списков, ViewHolders для разного типа ячеек и так далее. А можно использовать более быстрый подход без множества похожего кода на базе библиотеки Groupie

Groupie is a simple, flexible library for complex RecyclerView layouts.

Это простая и в тоже время мощная библиотека для упрощения построения списков на базе RecyclerView, которая заметно ускорит разработку сложных списков как в примерах выше.

Читайте также:  Андроид шутеры по блютуз

Безусловно, все что мы видели можно сделать и без этой библиотеки, тем более совсем недавно в Android появился MergeAdapter, о котором я писал в этой статье. Но так или иначе вы столкнётесь с недостатками стандартного подхода, описанного в той же статье. Поэтому, сегодня мы попробуем новый подход, ускоряющий разработку, избавляющий от написания бойлерплейт-кода и соответсвующий принципам SOLID.

Если кратко, то алгоритм действий выглядит следующим:

  1. Создаём проект. Добавляем нужные зависимости.
  2. Определяем нужные ячейки. Создаём layouts для отображения UI
  3. Соединяем ячейки с адаптером RecyclerView и наслаждаемся результатом.

Создание проекта и добавление библиотек.

Для создания списка как в примере на картинке нам понадобится 4 библиотеки: RecyclerView, CardView, Picasso (для отображения картинок) и Groupie. Добавим всё это в build.gradle(app):

Кроме этого, добавьте в build.gradle в блок android

Нажмите Sync Now для скачивания необходимых зависимостей.

Создание ячеек для отображения контента

Для отображения списка нам понадобится 3 типа ячеек:

  1. Общая ячейка — контейнер для отображения вложенного списка. Обозначена красным прямоугольником.
  2. Ячейка внутри основной ячейки для отображения информации о фильме. Такие ячейки выделены синим прямоугольником. Они находятся внутри основной ячейки в RecyclerView c горизонтальным скролом.
  3. Квадратная ячейка для отображения обложек игр. Выделена зелёным цветом.

Создание главной ячейки с вложенным RecyclerView

Вначале создадим общую ячейку с вложенным RecyclerView для отображения более мелких ячеек.

Вёрстка такой ячейки будет состоять из CardView с LinearLayout для отображения названия, описания и RecyclerView для отображения внутренних ячеек.

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

Каждая ячейка при использовании Groupie должна быть наследником от абстрактного класса Item. Для этого необходимо переопределить всего 2 метода getLayout() и bind(). То есть для создания ячейки вам нужно указать layout который будет использоваться для отображения UI и дописать логику формирования данных для этой ячейки и всё! Теперь не нужно писать однотипные адаптеры для разных ячеек или комбинировать множество разных типов ячеек в одном адаптере, нарушая принципы SOLID. Ну или выдумывать базовые классы для ячеек, только для того, чтобы можно было переиспользовать один и тот же адаптер. C Groupie для каждой ячейки вам необходимо создать свой класс, и описать в нем UI!

В данном пример мы будем использовать одну общую ячейку, которая на вход принимает название, описание и список других Item, то есть ячеек, которые и будут наполнять вложенный в эту ячейку RecyclerView. Самое интересное тут, пожалуй вот эта строчка:

То есть для RecyclerView который внутри этой ячейки, необходимо добавить общий GroupAdapter и наполнить его ячейками, которые являются наследниками Item.

Общий контейнер готов, теперь осталось сверстать частные ячейки для каждого типа контента. Их будет 2:

  1. Ячейка для фильма с названием фильма
  2. Квадратная ячейка с обложкой игры

Ячейка для фильма

Ячейка для фильма, также должна быть наследником Item и должна реализовать 2 метода:

Верстка достаточно простая и код можно посмотреть в проекте на GitHub.

Квадратная ячейка для отображения обложки игры

Эта ячейка тоже является достаточно простой, поэтому лучше посмотрите код проекта.

Все вместе. Соединяем все ячейки вместе

Для создания списка теперь нужно создать ячейки с контентом и передать их в адаптер RecyclerView. Для создания ячеек были созданы 2 метода getPopularMovies() и getPopularGames() которые возвращают ячейки типа Item.

Каждый из методов возвращает 1 ячейку MainCardContainer — которой передаётся в качестве аргумента список ячеек уже с контентом для вложенного RecyclerView. Например, для ячейки которая отображает список фильмов нужно указать список ячеек MovieItem. Для второй ячейки, которая отображает список игр — мы создадим также метод, который создаст основную общую ячейку и передаст ячейки с играми.

В итоге создание списка теперь будет выглядеть так:

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

Ну вот и всё! Буквально за 30 минут мы создали сложный список для отображения различного типа контента с вложенным горизонтальным списком! Сравните такой подход с традиционным и сделайте выводы сами! Абсолютно точно такой подход сэкономит вам время на разработку подобных UI — компонентов и избавит от кучи бесполезного кода. Хотите узнать ещё больше продвинутых фишек? Успейте записаться на онлайн-интенсив по Android-разработке

Понравилась статья? Не забудь подписаться и поставить лайк, а ещё

Источник

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 :

А можно воспользоваться стандартными макетами, к которым можно обращаться через 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 застовляет ближайший к центру элемент вставать в центр экрана. Допустим вы листаете список и в какой-то момент убрали пальцы от экрана. Список без вашего участия автоматически прокрутится и установит в центр экрана ближайший элемент.

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

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

Читайте также:  Обмен файлами между андроид устройствами по wifi

Первая появившаяся мысль — добавить на экран два 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.

Источник

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