Recyclerview divider in android

TutorialsBuzz

RecyclerView is a ViewGroup ,that display a scrolling list of elements based on large data sets (or data that frequently changes). RecyclerView widget is more flexible and efficient version of ListView .

In the previous tutorial we have seen basic example of recyclerView and recyclerView item click , In this tutorial we will see how to add divider to item of recyclerView .

Project Detail

Project Name RecyclerView
Package com.tutorialsbuzz.recyclerview
Min Sdk Version 22
Target Sdk Version 29
Compile Sdk Version 29
Theme Theme.AppCompat.Light.DarkActionBar

Adding RecyclerView To Layout

Adapter and ViewHolder For RecyclerView .

1. XML Layout for RecyclerView Item :

We will read json file kept inside asset folder and map it data class .

3. Adapter and Viewholder :

Divider For RecyclerView Items (ItemDecortion)

Create a rectangle shape drawable , set its width , height and set color .(This drawable is added between items of recyclerView)

Create a class SimpleDividerItemDecoration and extend it to ItemDecoration . Inside onDrawOver function draw the above defined drawable using canvas object .

Adding CustomItemDecortion to recyclerView .

To add ItemDecorator call addItemDecoration using recyclerView reference and pass the instance of above defined SimpleDividerItemDecoration

Источник

RecyclerView Android with Dividers and Contextual Toolbar

Android Tutorial

Today we’ll be developing a RecyclerView Android app with contextual toolbar to let us select, delete or mark the rows of a RecyclerView. Furthermore, we’ll place dividers between RecyclerView rows.

RecyclerView Android with Dividers and Contextual Toolbar Demo

We’ll be developing an application that displays the number of rows selected. Our app will allow us to delete, mark, refresh and select all rows.

A preview of what we’ll going to achieve by the end of this tutorial is given below.

RecyclerView Android Example

ActionMode is used to display the contextual toolbar when a row is long pressed in the list. This enables us to provide a set of alternative toolbar icons.

We’ll be implementing the four action modes present on the top right.

  1. Reload list
  2. Mark row text
  3. Delete row
  4. Select all rows

To implement the Contextual Toolbar and the above actions, we’ll need to implement the ActionMode.Callback interface in our MainActivity.java class.

The ActionMode.Callback interface consists of 4 methods that we’ll be overriding.

  1. onCreateActionMode: The menu.xml file is inflated in this method.
  2. onPrepareActionMode: This is called every time the Contextual Toolbar is shown.
  3. onActionItemClicked: This is invoked every time a menu item from the Contextual Toolbar is clicked.
  4. onDestroyActionMode: This is invoked when the Contextual Toolbar is closed.

RecyclerView android dependencies

Let’s start off by adding the following dependencies in our gradle build file.

Set the activity’s theme to AppTheme.NoActionBar in the Manifest.xml file as shown below.

RecyclerView Android Example Project Structure

The code for activity_main.xml is given below.

The code for content_main.xml is given below:

The layout code for each row of the RecyclerView is given in the file recyclerview_list_row.xml .

Читайте также:  Панель уведомлений андроид что это

The background of the RelativeLayout is a StateListDrawable (bg_list_row.xml) that’ll change its background when the row is selected/deselected.

The code for bg_list_row.xml is given below:

The menu that’ll be displayed inside the Contextual Toolbar is defined in the file menu_action_mode.xml as shown below.

We’ve created a custom ItemDecoration for displaying dividers for each of the rows. The code for DividerItemDecoration.java is given below.

The above code creates a divider line (similar to ListView) after each RecyclerView row based on the orientation.

The code for Model.java that holds the data for each row is given below.

The code for RecyclerViewAdapter.java is given below:

The following code snippet is used to change the state of the StateListDrawable.

The methods selectAll() , removeData() and updateData() would be invoked from the MainActivity.java based on the menu item clicked.

The code for MainActivity.java is given below.

The following code is used to add dividers between the rows.

onRowClicked() and onRowLongClicked() are called every time a RecyclerView row is clicked.

enableActionMode() is used to show the Contextual Toolbar.

The Contextual Toolbar displays the number of rows selected based upon the getSelectedItemCount() from the adapter class.

If all the rows are deleted, we show a floating action button that lets the user populate the RecyclerView with dummy data once again.

The output of the above application in action is given below.

Contextual Toolbar is commonly seen in applications like Whatsapp and Inbox.

This brings an end to the RecyclerView Android example with divider and selectors. You can download the final Android RecyclerViewDividersAndSelectors Project from the link below.

Источник

RecyclerView.ItemDecoration: используем по максимуму

Привет, дорогой читатель Хабра. Меня зовут Олег Жило, последние 4 года я Android-разработчик в Surf. За это время я поучаствовал в разного рода крутых проектах, но и с легаси-кодом поработать довелось.

У этих проектов есть как минимум одна общая деталь: везде при разработке приложения использовался список с элементами. Например, список контактов телефонной книги или список настроек вашего профиля.

В наших проектах для списков используется RecyclerView. Я не буду рассказывать, как писать Adapter для RecyclerView или как правильно обновлять данные в списке. В своей статье расскажу о другом важном и часто игнорируемом компоненте — RecyclerView.ItemDecoration, покажу как его применить при вёрстке списка и на что он способен.

Кроме данных в списке в RecyclerView есть ещё важные элементы декора, например, разделители ячеек, полосы прокрутки. И вот тут нам поможет RecyclerView.ItemDecoration отрисовать весь декор и не плодить лишние View в вёрстке ячеек и экрана.

ItemDecoration представляет из себя абстрактный класс с 3-мя методами:

Метод для отрисовки декора до отрисовки ViewHolder

Метод для отрисовки декора после отрисовки ViewHolder

Метод для выставления отступов у ViewHolder при заполнении RecyclerView

По сигнатуре методов onDraw* видно, что для отрисовки декора используется 3 основных компонента.

  • Canvas — для отрисовки необходимого декора
  • RecyclerView — для доступа к параметрам самого RecyclerVIew
  • RecyclerView.State — содержит информацию о состоянии RecyclerView

Подключение к RecyclerView

Для подключения экземпляра ItemDecoration к RecyclerView есть два метода:

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

Читайте также:  Как с андроида перенести файлы флешки

Также RecyclerView имеет дополнительные методы для манимуляции с ItemDecoration.
Удаление ItemDecoration по индексу

Удаление экземпляра ItemDecoration

Получить ItemDecoration по индексу

Получить текущее количество подключенных ItemDecoration в RecyclerView

Перерисовать текущий список ItemDecoration

В SDK уже есть наследники RecyclerView.ItemDecoration, например, DeviderItemDecoration. Он позволяет отрисовать разделители для ячеек.

Работает очень просто, необходимо использовать drawable и DeviderItemDecoration отрисует его в качестве разделителя ячеек.

И подключим DividerItemDeoration к RecyclerView:

Идеально подходит для простых случаев.

Под «капотом» DeviderItemDecoration всё элементарно:

На каждый вызов onDraw(. ) циклом проходим по всем текущим View в RecyclerView и отрисовываем переданный drawable.

Но экран может содержать и более сложные элементы вёрстки, чем список одинаковых элементов. На экране могут присутствовать:

а. Несколько видов ячеек;
b. Несколько видов дивайдеров;
c. Ячейки могут иметь закругленные края;
d. Ячейки могут иметь разный отступ по вертикали и горизонтали в зависимости от каких-то условий;
e. Всё вышеперечисленное сразу.

Давайте рассмотрим пункт e. Поставим себе сложную задачу и рассмотрим её решение.

  • На экране есть 3 вида уникальных ячеек, назовём их a, b и с.
  • Все ячейки имеют отступ в 16dp по горизонтали.
  • Ячейка b имеет ещё отступ в 8dp по вертикали.
  • Ячейка a имеет закруглённые края сверху, если это первая ячейка в группе и снизу, если это последняя ячейка в группе.
  • Между ячейками с отрисовываются дивайдеры, НО после последней ячейки в группе дивайдера быть не должно.
  • На фоне ячейки c рисуется картинка с эффектом параллакса.

Должно в итоге получиться так:

Рассмотрим варианты решения:

Заполнение списка ячейками разного типа.

Можно написать свой Adapter, а можно использовать любимую библиотеку.
Я буду использовать EasyAdapter.

Выставление отступов ячейкам.

Тут есть три способа:

  1. Проставить paddingStart и paddingEnd для RecyclerView.
    Данное решение не подойдёт, если не у всех ячеек отступ одинаковый.
  2. Проставить layout_marginStart и layout_marginEnd у ячейки.
    Придётся всем ячейкам в списке проставлять одни и те же отступы.
  3. Написать реализацию ItemDecoration и переопределить метод getItemOffsets.
    Уже лучше, решение получится более универсальное и переиспользуемое.

Закругление углов у групп ячеек.

Решение кажется очевидным: хочется сразу добавить какой-нибудь enum и проставлять его ячейке вместе с данными. Но сразу всплывают минусы:

  • Модель данных в списке усложняется.
  • Для таких манипуляций придётся заранее просчитывать какой enum проставлять каждой ячейке.
  • После удаления/добавления элемента в список придётся это пересчитывать заново.
  • ItemDecoration. Понять какая это ячейка в группе и правильно отрисовать фон можно в методе onDraw* ItemDecoration’a.

Рисование дивайдеров.

Рисование дивайдеров внутри ячейки — плохая практика, так как в итоге получится усложненная вёрстка, на сложных экранах начнутся проблемы с динамическим показом дивайдеров. И поэтому ItemDecoration снова выигрывает. Готовый DeviderItemDecoration из sdk нам не подойдёт, так как отрисовывает дивайдеры после каждой ячейки, и это никак не решается из коробки. Надо писать свою реализацию.

Паралакс на фоне ячейки.

На ум может прийти идея проставить RecyclerView OnScrollListener и использовать какую-нибудь кастомную View для отрисовки картинки. Но и здесь нас снова выручит ItemDecoration, так как он имеет доступ к Canvas Recycler’а и ко всем нужным параметрам.

Итого, нам необходимо написать как минимум 4 реализации ItemDecoration. Очень хорошо, что все пункты можем свести к работе только с ItemDecoration и не трогать вёрстку и бизнес логику фичи. Плюс, все реализации ItemDecoration получится переиспользовать, если у нас есть похожие кейсы в приложении.

Читайте также:  Планшет android gps bluetooth

Однако последние несколько лет у нас в проектах всё чаще появлялись сложные списки и приходилось писать каждый раз набор ItemDecoration под нужды проекта. Было необходимо более универсальное и гибкое решение, чтобы была возможность переиспользовать на других проектах.

Каких целей хотелось добиться:

  1. Писать как можно меньше наследников ItemDecoration.
  2. Отделить логику отрисовки на Canvas и выставления отступов.
  3. Иметь преимущества работы с методами onDraw и onDrawOver.
  4. Сделать более гибкие в настройке декораторы (например, отрисовка дивайдеров по условию, а не всех ячеек).
  5. Сделать решение без привязки к Дивайдерам, ведь ItemDecoration способен на большее, чем рисование горизонтальных и вертикальных линий.
  6. Этим можно легко пользоваться, смотря на сэмпл проект.

В итоге у нас получилась библиотека RecyclerView decorator.

Библиотека имеет простой Builder интерфейс, отдельные интерфейсы для работы с Canvas и отступами, также возможность работать с методами onDraw и onDrawOver. Реализация ItemDecoration всего одна.

Давайте вернёмся к нашей задаче и посмотрим, как её решить с помощью библиотеки.
Builder нашего декоратора выглядит просто:

  • .underlay(. ) — нужен для отрисовки под ViewHolder.
  • .overlay(. ) — нужен для отрисовки над ViewHolder.
  • .offset(. ) — используется для выставления отступа ViewHolder.

Для отрисовки декора и выставления отступов используется 3 интерфейса.

  • RecyclerViewDecor — отрисовывает декор на RecyclerView.
  • ViewHolderDecor — отрисовывает декор на RecyclerView, но даёт доступ к ViewHolder.
  • OffsetDecor — используется для выставления отступов.

Но это не всё. ViewHolderDecor и OffsetDecor можно привязать к конкретному ViewHolder с помощью viewType, что позволяет комбинировать несколько видов декоров на одном списке и даже ячейке. Если viewType не передавать, то ViewHolderDecor и OffsetDecor будут применяться ко всем ViewHolder в RecyclerView. RecyclerViewDecor такой возможности не имеет, так как рассчитан на работу с RecyclerView в общем, а не с ViewHolder’ами. Плюс один и тот же экземпляр ViewHolderDecor/RecyclerViewDecor можно передавать как в overlay(. ) так underlay(. ).

Приступим к написанию кода

В библиотеке EasyAdapter для создания ViewHolder используются ItemController’ы. Если коротко, они отвечают за создание и идентификацию ViewHolder. Для нашего примера хватит одного контроллера, который может отображать разные ViewHolder. Главное, чтобы viewType был уникальный для каждой вёрстки ячейки. Выглядит это следующим образом:

Для выставления отступов нам нужен наследник OffsetDecor:

Для отрисовки закруглённых углов у ViewHolder нужен наследник ViewHolderDecor. Тут нам понадобится OutlineProvider, чтобы press-state тоже обрезался по краям.

Для рисования дивайдеров напишем ещё одного наследника ViewHolderDecor:

Для настройки нашего дивадера будем использовать класс Gap.kt:

Он поможет настроить цвет, высоту, горизонтальные отступы и правила отрисовки дивайдера

Остался последний наследник ViewHolderDecor. Для рисования картинки эффектом параллакса.

Соберём теперь всё вместе.

Инициализируем RecyclerView, добавим ему наш декоратор и контроллеры:

На этом всё. Декор нашего списка готов.

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

Посмотрим как ещё можно применить декораторы.

PageIndicator для горизонтального RecyclerView

ChatActivityView.kt
TimeLineActivity.kt

Заключение

Несмотря на простоту интерфейса ItemDecoration, он позволяет делать сложные вещи со списком без изменения вёрстки. Надеюсь мне удалось показать, что это достаточно мощный инструмент и он достоин вашего внимания. А наша библиотека поможет вам декорировать списки проще.

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

UPD: 06.08.2020 добавлен пример для Sticky header

Источник

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