- Кастомный ItemDecoration для RecyclerView
- 1. Простой ItemDecoration : DividerItemDecoration
- 2. Custom ItemDecoration
- 2.1. Меняем ItemDecoration в зависимости позиции элемента
- 2.2. Удаляем ItemDecoration в конце списка
- 2.3. Оформление в зависимости от типа View
- Советы для профессионального использования RecyclerView. Часть 2
- 1. ItemDecoration
- 2. ItemAnimator
- Русские Блоги
- Три метода RecyclerView для установки разделителя
- 1. Самый простой способ (верстка и строчка)
- Два, можно указать ширину и цвет шаблона (готовый шаблон)
- Инструкции:
- Добавить разделительную линию по умолчанию: высота 2 пикселя, цвет серый
- Добавить настраиваемую разделительную линию: настраиваемая разделительная линия с возможностью рисования
- Добавьте настраиваемую разделительную линию: высоту и цвет разделительной линии можно настроить
- Универсальная разделительная линия здесь:
- В-третьих, используйте подробное введение содержимого в формате xml (с подробными примечаниями)
- 1. Общие сведения о ChildView в ListView и RecyclerView
- Таким образом, после того, как мы разберемся с ChildView, нам будет намного проще понять принцип добавления разделителя.
- 2. Разберитесь в принципе соединения разделителя.
- 3. Обсуждение дешево, покажите код.
Кастомный ItemDecoration для RecyclerView
Предисловие переводчика:
Оригинальная статья содержит GIF-анимации с демонстрацией работы кода (т. е. результат). К сожалению, мне не удалось вставить их в статью, т. к. я использовал новый редактор от Хабра, а он очень криво работает с изображениями 🙂 Для просмотра анимаций, вы можете перейти к оригинальной статье
Как-то раз мне нужно было создать собственный ItemDecoration, и я обнаружил, что в Интернете. почти нет ответов на этот вопрос. Надеюсь, что эта статья будет кому-нибудь полезна.
Простой ItemDecoration
Кастомный ItemDecoration
ItemDecoration основанный на позиции
ItemDecoration без отрисовки после последнего списка
ItemDecoration основанный на типе View
1. Простой ItemDecoration : DividerItemDecoration
Основной вариант использования может быть реализован с помощью DividerItemDecoration предоставляемый Android-ом.
Создает разделитель RecyclerView.ItemDecoration который можно использовать с LinearLayoutManager.
@param context […] будет использоваться для доступа к ресурсам.
@param orientation […] должен быть #HORIZONTAL или #VERTICAL.
Что вам нужно, так это установить правильную ориентацию, а затем предоставить drawable-ресурс, используемый для разделения каждого элемента.
Преимущества
Предоставляется самим Android
Прост в использовании
Недостатки
Как было упомянуто: ограниченные варианты использования — в качестве разделителя пустым пространством или линией.
Ограничение при использовании и «бесконечной» прокруткой (или пагинацией): декоратор будет отрисован для каждого элемента, в том числе и последнего. В большинстве случаев мы этого не хотим.
2. Custom ItemDecoration
Для лучшего контроля и более сложных вещей мы расширим RecyclerView.ItemDecoration.
Нам доступны 3 метода:
getItemOffsets используется для определения расстояния между элементами.
onDraw используется для отрисовки в пространстве между элементами.
onDrawOver то же, что и onDraw, только вызывается после того, как сам элемент отрисован.
? Cм. официальную документацию: getItemOffsets , onDraw , onDrawOver .
? Обратите внимание, что в примерах используется горизонтальная ориентация, но то же самое можно сделать и с вертикальной.
2.1. Меняем ItemDecoration в зависимости позиции элемента
Для начала простой пример: давайте украсим элементы с нечетной позицией в адаптере.
Кастомный ItemDecoration на основе позиции View
Главный метод здесь здесь parent.getChildAdapterPosition (view)
Он возвращает позицию переданной View в адаптере. См. полную документацию.
⚠️ Не путать с дочерними позициями родителей ( parent.children — это элементы, отображаемые на экране).
⚠️ Не забудьте обработать случай с RecyclerView.NO_POSITION , т. к. getChildAdapterPosition может вернуть -1.
2.2. Удаляем ItemDecoration в конце списка
Это наиболее распространенный вариант использования на StackOverflow, о котором вы спрашиваете. Это кастомный ItemDecoration , основанный на позиции элемента в адаптере.
Пользовательское оформление DividerItemDecoration, за исключением последнего элемента
Исключим последний элемент, добавив if (childAdapterPosition == adapter.itemCount-1) .
⚠️ Нужно помнить, что parent.adapter может быть null.
? Обратите внимание, что в большинстве случаев вам, вероятно, нужен только интервал между вашими элементами (за исключением последнего). Нет необходимости переопределять метод onDraw , достаточно установить правильный размер Rect в методе getItemsOffsets.
Пользовательский DividerItemDecoration, с добавлением интервала между элементами, за исключением последнего
2.3. Оформление в зависимости от типа View
В этом примере у нас есть 2 типа элементов, показанных черным и серым. Мы оформляем элементы синими и красными Drawable в зависимости от типа View (объявленных в Adapter-е ).
Пользовательский ItemDecoration в зависимости от типа View
Главная строчка кода здесь здесь — adapter.getItemViewType(childAdapterPosition) . Нам нужно переопределить метод getItemViewType в нашем адаптере.
Он возвращает тип View элемента по позиции для повторного использования View. […] Подумайте над тем, чтобы использовать id-ресурсы для уникальной идентификации типов View.
Как только вы сможете определить тип вашего элемента, вы можете установить правильный интервал и украсить его по своему желанию ?.
Вы можете найти полный код в моём GitHub репозитории.
Источник
Советы для профессионального использования RecyclerView. Часть 2
Продолжая предыдущую статью, в этой я расскажу про ItemDecoration и ItemAnimator и постараюсь объяснить принцип их работы в RecyclerView на примере простого приложения, которое доступно на Github.
1. ItemDecoration
ItemDecoration используется для декорирования элементов списка в RecyclerView .
С помощью ItemDecoration вы сможете добавлять разделители между view -компонентам, выравнивать их или разбивать равными промежутками. Чтобы добавить простой разделитель между view -компонентами, воспользуйтесь классом DividerItemDecoration , который можно найти в библиотеке поддержки версии 25.1.0 и выше. Следующий фрагмент кода демонстрирует его реализацию:
Лучший способ создания собственного разделителя — расширение класса RecyclerView.ItemDecoration . В примере приложения я использовал GridLayoutManager и применил CharacterItemDecoration к RecyclerView :
Здесь CharacterItemDecoration устанавливает смещение (англ. offset) на 50 пикселей в своём конструкторе и переопределяет getItemOffsets(. ) . Внутри метода getItemOffsets() каждое поле outRects определяет количество пикселей, которые необходимо установить для каждого view -компонента, подобно внутренним и внешним отступам. Поскольку я использовал GridLayoutManager и хотел настроить равные расстояния между элементами сетки, я установил отступ справа в 25 пикселей (т.е. offset/2) для каждого чётного элемента и отступ слева в 25 пикселей для каждого нечётного элемента, сохраняя при этом верхний отступ одинаковым для всех элементов.
2. ItemAnimator
ItemAnimator используется для анимации элементов или view -компонентов внутри RecyclerView .
Давайте сделаем наше приложение «Инстаграмоподобным», расширив DefaultItemAnimator и переопределив несколько методов.
Метод canReuseUpdatedViewHolder(. ) определяет, будет ли один и тот же ViewHolder использоваться для анимации, если данные этого элемента изменятся. Если он возвращает false , то оба ViewHolders — старый и обновленный — передаются в метод animateChange(. ) .
RecyclerView вызывает метод recordPreLayoutInformation(. ) до начала отрисовки layout . ItemAnimator должен записывать необходимую информацию о view -компоненте до того, как он будет перезаписан, перемещен или удалён. Данные, возвращаемые этим методом, будут переданы соответствующему методу анимации (в нашем случае это animateChange(. ) ).
RecyclerView вызывает метод animateChange(. ) , когда элемент адаптера присутствует одновременно до и после отрисовки после вызова метода notifyItemChanged(int) . Этот метод также можно использовать, при вызове notifyDataSetChanged() , если при этом в адаптере используются стабильные идентификаторы. Это необходимо для того, чтобы RecyclerView мог переиспользовать view -компоненты в тех же ViewHolders . Обратите внимание на то, что этот метод принимает в качестве аргументов: (ViewHolder oldHolder, ViewHolder newHolder, ItemHolderInfo preInfo, ItemHolderInfo postInfo). Поскольку мы повторно используем ViewHolder , оба — oldHolder и newHolder — одинаковы.
Всякий раз, когда пользователь дважды кликает на любой элемент, вызывается следующий метод:
Это запускает всю цепочку вызовов: canReuseUpdatedViewHolder(. ) , recordPreLayoutInformation(. ) и, в конечном итоге, animateChange(. ) в ItemAnimator , который, в свою очередь, анимирует элемент списка и иконку сердечка в этом элементе (пример на гифке выше).
Это вторая часть серии статей про RecyclerView . Если пропустили первую часть, то читайте её здесь.
Ещё несколько хороших статей на тему RecyclerView :
Источник
Русские Блоги
Три метода RecyclerView для установки разделителя
1. Самый простой способ (верстка и строчка)
Укажите разделительную линию внизу файла item.xml, например:
- xml version = “1.0” encoding = “utf-8” ?>
- LinearLayout xmlns:android = “http://schemas.android.com/apk/res/android”
- android:orientation = “vertical” android:layout_width = “match_parent”
- android:layout_height = “wrap_content” >
- LinearLayout
- android:orientation = “horizontal”
- android:layout_width = “match_parent”
- android:layout_height = “wrap_content” >
- ImageView
- android:id = “@+id/image_view”
- android:layout_gravity = “center”
- android:layout_width = “wrap_content”
- android:layout_height = “wrap_content”/>
- TextView
- android:id = “@+id/text_view”
- android:layout_gravity = “center”
- android:gravity = “left”
- android:layout_marginTop = “10dp”
- android:layout_width = “wrap_content”
- android:layout_height = “wrap_content”/>
- LinearLayout >
- span style = “color:#ff0000;” > View
- android:layout_width = “match_parent”
- android:layout_height = “1dp”
- android:layout_marginTop = “10dp”
- android:background = “@color/colorPrimary”/> span >
- LinearLayout >
Два, можно указать ширину и цвет шаблона (готовый шаблон)
Инструкции:
Добавить разделительную линию по умолчанию: высота 2 пикселя, цвет серый
Добавить настраиваемую разделительную линию: настраиваемая разделительная линия с возможностью рисования
Добавьте настраиваемую разделительную линию: высоту и цвет разделительной линии можно настроить
Универсальная разделительная линия здесь:
В-третьих, используйте подробное введение содержимого в формате xml (с подробными примечаниями)
Буквально вчера в полдень я опубликовал свой первый личный технический документ по короткой книге: RecyclerView series: Серия RecyclerView (1) добавить верхний и нижний колонтитулы в RecyclerView, Мне также повезло, что я смог заручиться поддержкой такого количества людей, что мне не терпится написать вторую статью. Сегодня я расскажу о: добавлении разделителя для RecyclerView.
1. Общие сведения о ChildView в ListView и RecyclerView
Прежде чем говорить о сути добавления разделительной линии к элементу, давайте сначала представим его и познакомимся с ChildView, который мы обычно используем ListView. Какая часть ChildView возвращается getChildAt (int position) в RecyclerView? Какая это часть? Вначале я ошибся, но сравнив следующие две картинки, вы поймете:
Посмотрите на разницу между приведенным ниже кодом:
Код первого изображения, то есть файл макета каждого list_item (то же самое ниже), выглядит следующим образом:
Код для второй картинки:
Присмотритесь, разница между ними в том, что на второй диаграмме больше кода:
Еще одно предложение.
Итак, здесь мы должны знать, какая часть является частью ChildView, а это зеленая часть на рисунке 2. Часть поля не принадлежит ChildView, но принадлежит макету ChildView.
Таким образом, после того, как мы разберемся с ChildView, нам будет намного проще понять принцип добавления разделителя.
2. Разберитесь в принципе соединения разделителя.
В ListView Google предоставляет нам такой метод, как SetDivider (Drawable divider) для установки разделительных линий. Затем в RecyclerView, какой метод Google предоставляет нам для добавления разделительных линий? В официальной документации можно найти: addItemDecoration (RecyclerView.ItemDecoration decor) Этот метод используется для установки разделителя. Тогда снова возникает вопрос, что такое RecyclerView.ItemDecoration? Продолжил проверку: и обнаружил следующее: это оказался класс, в котором были заключены три метода:
(1)void getItemOffsets ()
(2)void onDraw ()
(3)void onDrawOver ()
С помощью трех вышеперечисленных методов можно увидеть, что это рисование непосредственно самостоятельно. Если быть точным, это следующие методы: добавить разделитель, в основном, чтобы найти позицию добавления разделителя, и разделитель записывается в файл с возможностью рисования. . Использование onDraw и onDrawOver практически одинаково.Когда мы создаем наш класс Decoration для наследования RecyclerView.ItemDecoration, нам нужно только переопределить getItemOffsets (), а также один из onDraw () и onDrawOver.
Какая польза от метода getItemOffsets ()? Буквальное значение состоит в том, что элемент должен быть смещен. Поскольку мы добавили разделительную линию между элементом и элементом, линия на самом деле представляет собой прямоугольник, который также определяется пользователем. Поскольку линия также имеет длину, ширину и высоту, нарисуйте горизонтальную линию. Если элемент добавлен к разделительной линии, элемент ниже переместится вниз, а величина перевода будет равна высоте разделительной линии. Если вы не понимаете каждую взаимосвязь, это будет легко понять, просмотрев код позже.
Теперь мы знаем, как добавить его, просто раскрашивая. Где картина? Как определить положение картины? Посмотрите на картинку ниже:
Позвольте мне теперь взять рисование горизонтальных линий в качестве примера. Из приведенного выше рисунка мы можем легко увидеть, что положение, где мы проводим разделительную линию, находится между макетом каждого элемента. Примечание: оно находится между макетами.
Итак, мы определились, где рисовать, тогда как нам определить конкретное координатное положение линии? То есть мы должны определить: левую, верхнюю, правую, нижнюю часть разделителя. В адаптере мы можем легко получить каждый childView через родительский элемент (этот родительский элемент фактически является той частью, которую мы видим):
(1)left:parent.getPaddingLeft()
(2)right: parent. getWidth()-parent.getPaddingRight();
(3) top: над красной линией: мы используем ChildView.getBottom (), чтобы получить высоту нижней части элемента, то есть положение синей линии, расстояние между синей линией и красной линией: это файл макета элемента: layout_marginBottom, а затем Верхняя позиция — это сумма двух.
(4) bttom: высота верха плюс разделительная линия: верх + высота строки
Благодаря приведенному выше анализу вы можете узнать принцип добавления разделителя. Не имеет значения, если вы его не понимаете. Не очень ясно сказать, что он находится непосредственно в приведенном ниже коде и понять его через код.
3. Обсуждение дешево, покажите код.
(1) Во-первых, давайте посмотрим на основной файл макета: activity_main.xml:
Я только что добавил в него RecyclerView
(2) Файл макета каждого элемента в RecyclerView: item_view.xml
Не о чем говорить, просто добавьте TextView для отображения текста
(3) Наш адаптер RecyclerView MyAdapater.java:
Что ж, здесь не о чем говорить, и это не является целью данной статьи.
(4) Наш собственный MyDecoration.java: (унаследованный от RecyclerView.ItemDecoration)
Из приведенного выше кода мы также используем свойства системы для адаптации к горизонтальному и вертикальному экранам экрана, а затем определяем, рисовать ли горизонтальный или вертикальный разделитель. Фактически, мы сделали в нем три вещи, первая: получить систему В listDivider мы устанавливаем его в теме через него, и вы можете увидеть код, посмотрев на код в (6) ниже. Во-вторых, нужно найти место, куда нам нужно добавить разделитель, найти его с помощью метода onDraw и добавить разделитель. Третий: получить смещение элемента.
(5) Посмотрите наш MainActivity.java
(6) Файл с возможностью рисования разделителя: Dividerr.xml
Здесь мы нарисовали прямоугольник, залили его цветом и высотой, чтобы это было сделано, высота небольшая, и отображение тоже является линией: по сути, суть линии — это прямоугольник. Здесь вы можете нарисовать разные типы разделителей в соответствии с личными потребностями.
(7) В AppTheme файла styles.xml установите listDivider в качестве нашего файла Diviver.xml:
Таким образом, мы устанавливаем системный listDivider на наш настраиваемый разделитель. Помните, что мы получаем системное свойство listDivider в MyDecoration, так что через это свойство мы можем связать наш файл Diviver.xml с MyDecoration.java. Вверх.
Здесь все работы завершены, результаты бега показаны ниже:
После нескольких часов написания я наконец сделал это.Хотя это всего лишь функция добавления разделителя, я все же хочу понять это на моем родном языке, насколько это возможно, понять его принцип, это намного проще сделать. Вначале я не знал, как им пользоваться, и я также сослался на статьи, написанные другими, особенно Великим Богом Хунъяна:Android RecyclerView использует полное разрешение для художественного управленияНаписано очень хорошо, и кое-что почерпнуло из этого.
Хорошо, эта статья пока написана здесь. В ней кратко представлены принципы и методы добавления некоторых разделителей RecyclerView. Надеюсь, вы сможете сообщить больше. Я продолжу писать статью через несколько дней, серия RecyclerView (3) : Добавить в RecyclerView функции обновления в раскрывающемся списке и загрузки по запросу. Наконец, я хочу поблагодарить вас всех благодаря этой платформе, которая позволяет нам общаться и узнавать все вместе.
Источник