Intereting Posts
Android-приложение перезапускается автоматически после сбоя NullPointerException в handleStopActivity. Нет ссылки на мой код в трассировке стека. Как измерить прошедшее время Wifi-Direct всегда отключается через тридцать минут Как я могу получить данные с веб-сервера в приложении Android? Форма, выделенная в качестве фона, строка внизу Как обрабатывать сообщения обработчика, когда действие / фрагмент приостановлено Как ссылаться на атрибут color в drawable? Выполнение плагина не распространяется на конфигурацию жизненного цикла: com.jayway.maven.plugins.android.generation2: android-maven-plugin: 3.5.0: генерировать-источники Espresso: return boolean, если вид существует Как изменить значок меню в панели действий? Android google analytics v3: «Сервис недоступен» Android Media Recorder не записывает длинные видео в Google Glass Генерировать non-debug apk от ионного Разрешены ли общие настройки в приложениях Android, когда пользователь обновляет приложение?

Как добавить разделители и пробелы между элементами в RecyclerView?

Это пример того, как это можно было сделать ранее в классе ListView , используя параметры divider и dividerHeight :

 <ListView android:id="@+id/activity_home_list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="@android:color/transparent" android:dividerHeight="8dp"/> 

Однако я не вижу такой возможности в классе RecyclerView .

 <android.support.v7.widget.RecyclerView android:id="@+id/activity_home_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical"/> 

В этом случае, нормально ли определять поля и / или добавлять пользовательский вид разделителя непосредственно в макет элемента списка или есть лучший способ достичь моей цели?

Solutions Collecting From Web of "Как добавить разделители и пробелы между элементами в RecyclerView?"

Октябрь 2016 года

В версии 25.0.0 в Android Support Library представлен класс DividerItemDecoration :

DividerItemDecoration – это RecyclerView.ItemDecoration, которое может использоваться как разделитель между элементами LinearLayoutManager. Он поддерживает как HORIZONTAL, так и VERTICAL ориентации.

Применение:

 DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), layoutManager.getOrientation()); recyclerView.addItemDecoration(dividerItemDecoration); 

Предыдущий ответ

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


В отличие от ListView , класс RecyclerView не имеет параметров, связанных с делителем. Вместо этого вам необходимо расширить ItemDecoration , внутренний класс RecyclerView :

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

Все ItemDecorations рисуются в том порядке, в котором они были добавлены, перед представлением элемента (в onDraw ()) и после элементов (в onDrawOver (Canvas, RecyclerView, RecyclerView.State).

Вертикальный интервал ItemDecoration

Расширьте ItemDecoration , добавьте настраиваемый конструктор, который принимает значение высоты пространства в качестве параметра и переопределяет getItemOffsets() :

 public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration { private final int verticalSpaceHeight; public VerticalSpaceItemDecoration(int verticalSpaceHeight) { this.verticalSpaceHeight = verticalSpaceHeight; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.bottom = verticalSpaceHeight; } } 

Если вы не хотите вставлять пространство ниже последнего элемента, добавьте следующее условие:

 if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) { outRect.bottom = verticalSpaceHeight; } 

Примечание. Вы также можете изменить outRect.top , outRect.left и outRect.right для желаемого эффекта.

Разделитель ItemDecoration

Расширить ItemDecoration и переопределить onDraw() :

 public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; private Drawable divider; /** * Default divider will be used */ public DividerItemDecoration(Context context) { final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS); divider = styledAttributes.getDrawable(0); styledAttributes.recycle(); } /** * Custom divider will be used */ public DividerItemDecoration(Context context, int resId) { divider = ContextCompat.getDrawable(context, resId); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin; int bottom = top + divider.getIntrinsicHeight(); divider.setBounds(left, top, right, bottom); divider.draw(c); } } } 

Вы можете вызвать первый конструктор, который использует атрибуты разделителя Android по умолчанию, или второй, который использует ваш собственный drawable, например drawable / divider.xml

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:height="1dp" /> <solid android:color="#ff992900" /> </shape> 

Примечание. Если вы хотите, чтобы разделитель был нарисован над вашими элементами, вместо этого переопределите onDrawOver() .

Применение

Чтобы использовать новый класс, добавьте VerticalSpaceItemDecoration или DividerSpaceItemDecoration в RecyclerView , например, в метод onCreateView() вашего фрагмента:

 private static final int VERTICAL_ITEM_SPACE = 48; private RecyclerView recyclerView; private LinearLayoutManager linearLayoutManager; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_feed, container, false); recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_home_recycler_view); linearLayoutManager = new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(linearLayoutManager); //add ItemDecoration recyclerView.addItemDecoration(new VerticalSpaceItemDecoration(VERTICAL_ITEM_SPACE)); //or recyclerView.addItemDecoration(new DividerItemDecoration(getActivity())); //or recyclerView.addItemDecoration( new DividerItemDecoration(getActivity(), R.drawable.divider)); recyclerView.setAdapter(...); return rootView; } 

Также есть библиотека Lucas Rocha, которая должна упростить процесс украшения предметов. Не пробовал, хотя.

Среди его возможностей :

  • Коллекция украшений предметов, в том числе:
  • Разность позиций Горизонтальные / вертикальные разделители.
  • Элемент списка

Могу ли я обратить ваше внимание на этот конкретный файл на Github от Alex Fu: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

Это файл примера DividerItemDecoration.java «вытащил прямо из демонстрации поддержки». ( https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )

После импорта этого файла в мой проект я смог получить разделительные линии и добавить его в качестве украшения элемента для просмотра ресайклеров.

Вот как выглядит мой onCreateView в моем фрагменте, содержащем Recyclerview:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false); mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view); mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(getActivity()); mRecyclerView.setLayoutManager(mLayoutManager); mRecyclerView.setItemAnimator(new DefaultItemAnimator()); return rootView; } 

Я уверен, что дополнительный стиль можно сделать, но это отправная точка. 🙂

Простая реализация ItemDecoration для равных пробелов между всеми элементами.

 public class SpacesItemDecoration extends RecyclerView.ItemDecoration { private int space; public SpacesItemDecoration(int space) { this.space = space; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.left = space; outRect.right = space; outRect.bottom = space; // Add top margin only for the first item to avoid double space between items if(parent.getChildAdapterPosition(view) == 0) { outRect.top = space; } } } 

Простым является установка цвета фона для RecyclerView и другого цвета фона для элементов. Вот пример …

 <android.support.v7.widget.RecyclerView android:background="#ECEFF1" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="vertical"/> 

И элемент TextView (это может быть что угодно) с нижним полем «x» dp или px.

 <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="1dp" android:background="#FFFFFF"/> 1 <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="1dp" android:background="#FFFFFF"/> 

Выход …

Введите описание изображения здесь

Просто добавь

 recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL)); 

Также вам может потребоваться добавить зависимость
compile 'com.android.support:recyclerview-v7:25.3.1'

РЕДАКТИРОВАТЬ:

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

 DividerItemDecoration itemDecorator = new DividerItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL)); itemDecorator.setDrawable(getResources().getDrawable(R.drawable.divider)); 

Вы можете использовать любой пользовательский вариант, например:

 <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@color/colorPrimary"/> <size android:height="0.5dp"/> </shape> 

Я думаю, что использование простого делителя поможет вам

Чтобы добавить разделитель к каждому элементу:
1- Добавьте это в рисовальный каталог line_divider.xml

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:width="1dp" android:height="1dp" /> <solid android:color="#999999" /> </shape> 1 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:width="1dp" android:height="1dp" /> <solid android:color="#999999" /> </shape> 

2- Создать класс SimpleDividerItemDecoration
Я использовал этот пример для определения этого класса:
https://gist.github.com/polbins/e37206fbc444207c0e92

 package com.example.myapp; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.support.v7.widget.RecyclerView; import android.view.View; import com.example.myapp.R; public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration{ private Drawable mDivider; public SimpleDividerItemDecoration(Resources resources) { mDivider = resources.getDrawable(R.drawable.line_divider); } public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin; int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } } 

3- В действии или фрагменте, использующем RecyclerView, внутри onCreateView добавьте это:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { RecyclerView myRecyclerView = (RecyclerView) layout.findViewById(R.id.my_recycler_view); myRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getResources())); .... } 

4- Чтобы добавить расстояние между элементами
Вам просто нужно добавить свойство дополнения в свой вид товара

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="4dp" > ..... item structure </RelativeLayout> 

Поскольку я установил ItemAnimators . ItemDecorator не входит и не выходит вместе с анимацией.

Я просто оказался в строке представления в файле макета элемента для каждого элемента. Он решил мое дело. DividerItemDecoration чувствовал себя к большому количеству колдовства для простого делителя. Или, возможно, я пропустил его реальное использование.

 <View android:layout_width="match_parent" android:layout_height="1px" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="@color/lt_gray"/> 

Поскольку нет правильного способа реализовать это, но с использованием Material Design, я просто сделал следующий трюк, чтобы добавить разделитель в элемент списка напрямую:

 <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/dividerColor"/> 1 <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/dividerColor"/> 

ОКТЯБРЬ 2016 ОБНОВЛЕНИЕ

В библиотеке поддержки v25.0.0 наконец реализована стандартная реализация базовых горизонтальных и вертикальных разделителей!

https://developer.android.com/reference/android/support/v7/widget/DividerItemDecoration.html

Это фактически не решает проблему, но, как временное решение, вы можете установить свойство useCompatPadding на карте в вашем XML-макете, чтобы она была такой же, как и в версиях до Lollipop.

 card_view:cardUseCompatPadding="true" 

Для тех, кто ищет пробелы между элементами в RecyclerView см. Мой подход, в котором вы получаете равные промежутки между всеми элементами, за исключением первого и последнего элементов, где я дал большее дополнение. Я применяю только LayoutManager влево / вправо в горизонтальном LayoutManager и сверху / снизу в вертикальном LayoutManager .

 public class PaddingItemDecoration extends RecyclerView.ItemDecoration { private int mPaddingPx; private int mPaddingEdgesPx; public PaddingItemDecoration(Activity activity) { final Resources resources = activity.getResources(); mPaddingPx = (int) resources.getDimension(R.dimen.paddingItemDecorationDefault); mPaddingEdgesPx = (int) resources.getDimension(R.dimen.paddingItemDecorationEdge); } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); final int itemPosition = parent.getChildAdapterPosition(view); if (itemPosition == RecyclerView.NO_POSITION) { return; } int orientation = getOrientation(parent); final int itemCount = state.getItemCount(); int left = 0; int top = 0; int right = 0; int bottom = 0; /** HORIZONTAL */ if (orientation == LinearLayoutManager.HORIZONTAL) { /** all positions */ left = mPaddingPx; right = mPaddingPx; /** first position */ if (itemPosition == 0) { left += mPaddingEdgesPx; } /** last position */ else if (itemCount > 0 && itemPosition == itemCount - 1) { right += mPaddingEdgesPx; } } /** VERTICAL */ else { /** all positions */ top = mPaddingPx; bottom = mPaddingPx; /** first position */ if (itemPosition == 0) { top += mPaddingEdgesPx; } /** last position */ else if (itemCount > 0 && itemPosition == itemCount - 1) { bottom += mPaddingEdgesPx; } } if (!isReverseLayout(parent)) { outRect.set(left, top, right, bottom); } else { outRect.set(right, bottom, left, top); } } private boolean isReverseLayout(RecyclerView parent) { if (parent.getLayoutManager() instanceof LinearLayoutManager) { LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager(); return layoutManager.getReverseLayout(); } else { throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager."); } } private int getOrientation(RecyclerView parent) { if (parent.getLayoutManager() instanceof LinearLayoutManager) { LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager(); return layoutManager.getOrientation(); } else { throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager."); } } } 

dimens.xml

 <resources> <dimen name="paddingItemDecorationDefault">10dp</dimen> <dimen name="paddingItemDecorationEdge">20dp</dimen> </resources> 

Я разветвлял DividerItemDecoration из более старого стиля и упрощал его, чтобы он соответствовал моему варианту использования, и я также модифицировал его, чтобы нарисовать разделители так, как они рисованы в ListView, включая разделитель после последнего элемента списка. Это также будет обрабатывать вертикальные анимации ItemAnimator:

1) Добавьте этот класс в свой проект:

 public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; private Drawable divider; public DividerItemDecoration(Context context) { try { final TypedArray a = context.obtainStyledAttributes(ATTRS); divider = a.getDrawable(0); a.recycle(); } catch (Resources.NotFoundException e) { // TODO Log or handle as necessary. } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if (divider == null) return; if (parent.getChildAdapterPosition(view) < 1) return; if (getOrientation(parent) == LinearLayoutManager.VERTICAL) outRect.top = divider.getIntrinsicHeight(); else throw new IllegalArgumentException("Only usable with vertical lists"); } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { if (divider == null) { super.onDrawOver(c, parent, state); return; } final int left = parent.getPaddingLeft(); final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; ++i) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int size = divider.getIntrinsicHeight(); final int top = (int) (child.getTop() - params.topMargin - size + child.getTranslationY()); final int bottom = top + size; divider.setBounds(left, top, right, bottom); divider.draw(c); if (i == childCount - 1) { final int newTop = (int) (child.getBottom() + params.bottomMargin + child.getTranslationY()); final int newBottom = newTop + size; divider.setBounds(left, newTop, right, newBottom); divider.draw(c); } } } private int getOrientation(RecyclerView parent) { if (!(parent.getLayoutManager() instanceof LinearLayoutManager)) throw new IllegalStateException("Layout manager must be an instance of LinearLayoutManager"); return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation(); } } 

2) Добавьте декоратор к вашему RecylerView:

 recyclerView.addItemDecoration(new DividerItemDecoration(getActivity())); 

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

 android:layout_marginTop="10dp" 

Если вы просто хотите добавить равный интервал и хотите сделать это в XML , просто установите padding к вашему RecyclerView и равное количество layoutMargin для элемента, который вы раздуваете в свой RecyclerView , и пусть цвет фона определяет цвет интервала.

  • Вот простой взлом для добавления разделителя
  • Просто добавьте фон в макет вашего элемента ресайклера следующим образом

     <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/shape_border" android:gravity="center" android:orientation="horizontal" android:padding="5dp" > <ImageView android:id="@+id/imageViewContactLogo" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginRight="10dp" android:src="@drawable/ic_user" /> <LinearLayout android:id="@+id/linearLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.92" android:gravity="center|start" android:orientation="vertical" > <TextView android:id="@+id/textViewContactName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/textViewStatusOrNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:singleLine="true" android:text="" android:textAppearance="?android:attr/textAppearanceMedium"/> </LinearLayout> <TextView android:id="@+id/textViewUnreadCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:padding="5dp" android:text="" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/red" android:textSize="22sp" /> <Button android:id="@+id/buttonInvite" android:layout_width="54dp" android:layout_height="wrap_content" android:background="@drawable/ic_add_friend" /> </LinearLayout> 

Создайте следующий файл shape_border.xml в папке с возможностью переноса.

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <gradient android:angle="270" android:centerColor="@android:color/transparent" android:centerX="0.01" android:startColor="#000" /> </shape> 

Вот окончательный результат – RecyclerView с разделителем.

Вот окончательный результат - просмотр ресайклера с разделителем

В результате поиска Google добавьте этот ItemDecoration в свой RecyclerView :

 public class DividerItemDecoration extends RecyclerView.ItemDecoration { private Drawable mDivider; private boolean mShowFirstDivider = false; private boolean mShowLastDivider = false; public DividerItemDecoration(Context context, AttributeSet attrs) { final TypedArray a = context .obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider}); mDivider = a.getDrawable(0); a.recycle(); } public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider, boolean showLastDivider) { this(context, attrs); mShowFirstDivider = showFirstDivider; mShowLastDivider = showLastDivider; } public DividerItemDecoration(Drawable divider) { mDivider = divider; } public DividerItemDecoration(Drawable divider, boolean showFirstDivider, boolean showLastDivider) { this(divider); mShowFirstDivider = showFirstDivider; mShowLastDivider = showLastDivider; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if (mDivider == null) { return; } if (parent.getChildPosition(view) < 1) { return; } if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { outRect.top = mDivider.getIntrinsicHeight(); } else { outRect.left = mDivider.getIntrinsicWidth(); } } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { if (mDivider == null) { super.onDrawOver(c, parent, state); return; } // Initialization needed to avoid compiler warning int left = 0, right = 0, top = 0, bottom = 0, size; int orientation = getOrientation(parent); int childCount = parent.getChildCount(); if (orientation == LinearLayoutManager.VERTICAL) { size = mDivider.getIntrinsicHeight(); left = parent.getPaddingLeft(); right = parent.getWidth() - parent.getPaddingRight(); } else { //horizontal size = mDivider.getIntrinsicWidth(); top = parent.getPaddingTop(); bottom = parent.getHeight() - parent.getPaddingBottom(); } for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); if (orientation == LinearLayoutManager.VERTICAL) { top = child.getTop() - params.topMargin; bottom = top + size; } else { //horizontal left = child.getLeft() - params.leftMargin; right = left + size; } mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } // show last divider if (mShowLastDivider && childCount > 0) { View child = parent.getChildAt(childCount - 1); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); if (orientation == LinearLayoutManager.VERTICAL) { top = child.getBottom() + params.bottomMargin; bottom = top + size; } else { // horizontal left = child.getRight() + params.rightMargin; right = left + size; } mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } private int getOrientation(RecyclerView parent) { if (parent.getLayoutManager() instanceof LinearLayoutManager) { LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager(); return layoutManager.getOrientation(); } else { throw new IllegalStateException( "DividerItemDecoration can only be used with a LinearLayoutManager."); } } } 

Мы можем украсить предметы, используя различные декораторы, прикрепленные к recyclerview, такие как DividerItemDecoration:

Просто используйте следующее … взятое из ответа EyesClear

 public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; private Drawable mDivider; /** * Default divider will be used */ public DividerItemDecoration(Context context) { final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS); mDivider = styledAttributes.getDrawable(0); styledAttributes.recycle(); } /** * Custom divider will be used */ public DividerItemDecoration(Context context, int resId) { mDivider = ContextCompat.getDrawable(context, resId); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin; int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } 

}, А затем используйте приведенное выше

 RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST); recyclerView.addItemDecoration(itemDecoration); 

Это отобразит разделители между каждым элементом в списке, как показано ниже:

Введите описание изображения здесь

И для тех, кто ищет более подробную информацию, вы можете ознакомиться с этим руководством. Использование RecyclerView _ CodePath Android Cliffnotes

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

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

Пожалуйста, дайте мне знать о любых сомнениях в комментариях ниже 🙂

If anyone is looking to only add, say, 10dp spacing between items, you can do so by setting a drawable to DividerItemDecoration :

 DividerItemDecoration dividerItemDecoration = new DividerItemDecoration( recyclerView.getContext(), layoutManager.getOrientation() ); dividerItemDecoration.setDrawable( ContextCompat.getDrawable(getContext(), R.drawable.divider_10dp) ); 

Where divider_10dp is a drawable resource containing:

 <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:height="10dp"/> <solid android:color="@android:color/transparent"/> </shape> 

If you want to add same space for items, the simplest way is to add top+left padding for RecycleView and right+bottom margins to card items.

dimens.xml

 <resources> <dimen name="divider">1dp</dimen> </resources> 

list_item.xml

 <CardView android:layout_marginBottom="@dimen/divider" android:layout_marginRight="@dimen/divider"> ... </CardView> 

list.xml

 <RecyclerView android:paddingLeft="@dimen/divider" android:paddingTop="@dimen/divider" /> 

This link worked like a charm for me:

https://gist.github.com/lapastillaroja/858caf1a82791b6c1a36

 import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.View; public class DividerItemDecoration extends RecyclerView.ItemDecoration { private Drawable mDivider; private boolean mShowFirstDivider = false; private boolean mShowLastDivider = false; public DividerItemDecoration(Context context, AttributeSet attrs) { final TypedArray a = context .obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider}); mDivider = a.getDrawable(0); a.recycle(); } public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider, boolean showLastDivider) { this(context, attrs); mShowFirstDivider = showFirstDivider; mShowLastDivider = showLastDivider; } public DividerItemDecoration(Drawable divider) { mDivider = divider; } public DividerItemDecoration(Drawable divider, boolean showFirstDivider, boolean showLastDivider) { this(divider); mShowFirstDivider = showFirstDivider; mShowLastDivider = showLastDivider; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if (mDivider == null) { return; } if (parent.getChildPosition(view) < 1) { return; } if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { outRect.top = mDivider.getIntrinsicHeight(); } else { outRect.left = mDivider.getIntrinsicWidth(); } } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { if (mDivider == null) { super.onDrawOver(c, parent, state); return; } // Initialization needed to avoid compiler warning int left = 0, right = 0, top = 0, bottom = 0, size; int orientation = getOrientation(parent); int childCount = parent.getChildCount(); if (orientation == LinearLayoutManager.VERTICAL) { size = mDivider.getIntrinsicHeight(); left = parent.getPaddingLeft(); right = parent.getWidth() - parent.getPaddingRight(); } else { //horizontal size = mDivider.getIntrinsicWidth(); top = parent.getPaddingTop(); bottom = parent.getHeight() - parent.getPaddingBottom(); } for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); if (orientation == LinearLayoutManager.VERTICAL) { top = child.getTop() - params.topMargin; bottom = top + size; } else { //horizontal left = child.getLeft() - params.leftMargin; right = left + size; } mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } // show last divider if (mShowLastDivider && childCount > 0) { View child = parent.getChildAt(childCount - 1); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); if (orientation == LinearLayoutManager.VERTICAL) { top = child.getBottom() + params.bottomMargin; bottom = top + size; } else { // horizontal left = child.getRight() + params.rightMargin; right = left + size; } mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } private int getOrientation(RecyclerView parent) { if (parent.getLayoutManager() instanceof LinearLayoutManager) { LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager(); return layoutManager.getOrientation(); } else { throw new IllegalStateException( "DividerItemDecoration can only be used with a LinearLayoutManager."); } } } 

Then in your activity:

 mCategoryRecyclerView.addItemDecoration( new DividerItemDecoration(this, null)); 

Or this if you are using a fragment:

 mCategoryRecyclerView.addItemDecoration( new DividerItemDecoration(getActivity(), null)); 

I have added a line in list item like below

 <View android:id="@+id/divider" android:layout_width="match_parent" android:layout_height="1px" android:background="@color/dividerColor"/> 

1px will draw the thin line.

If you want to hide the divider for the last row then divider.setVisiblity(View.GONE); on the onBindViewHolder for the last list Item.

You can add with programaticly easily.

If your Layout Manager is Linearlayout then you can use:

DividerItemDecoration is a RecyclerView.ItemDecoration that can be used as a divider between items of a LinearLayoutManager. It supports both HORIZONTAL and VERTICAL orientations.

  mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), mLayoutManager.getOrientation()); recyclerView.addItemDecoration(mDividerItemDecoration); 

источник

 public class CommonItemSpaceDecoration extends RecyclerView.ItemDecoration { private int mSpace = 0; private boolean mVerticalOrientation = true; public CommonItemSpaceDecoration(int space) { this.mSpace = space; } public CommonItemSpaceDecoration(int space, boolean verticalOrientation) { this.mSpace = space; this.mVerticalOrientation = verticalOrientation; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.top = SizeUtils.dp2px(view.getContext(), mSpace); if (mVerticalOrientation) { if (parent.getChildAdapterPosition(view) == 0) { outRect.set(0, SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace)); } else { outRect.set(0, 0, 0, SizeUtils.dp2px(view.getContext(), mSpace)); } } else { if (parent.getChildAdapterPosition(view) == 0) { outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, 0, 0); } else { outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace), 0); } } } } 

This will add space in every item's top and bottom(or left and right).Then you can set it to your recyclerView.

 recyclerView.addItemDecoration(new CommonItemSpaceDecoration(16)); 

SizeUtils.java

 public class SizeUtils { public static int dp2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } } 

A really easy solution is to use RecyclerView-FlexibleDivider

Add dependency:

 compile 'com.yqritc:recyclerview-flexibledivider:1.4.0' 

Add to your recyclerview:

 recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(context).build()); 

И вы сделали!

1.One of the Way is by using cardview and recycler view together we can easily add effect like divider. ех. https://developer.android.com/training/material/lists-cards.html

2.and other is by adding view as divider to list_item_layout of recycler view .

  <View android:id="@+id/view1" android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/colorAccent" /> 1  <View android:id="@+id/view1" android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/colorAccent" /> 

Implement its own version of RecyclerView.ItemDecoration

 public class SpacingItemDecoration extends RecyclerView.ItemDecoration { private int spacingPx; private boolean addStartSpacing; private boolean addEndSpacing; public SpacingItemDecoration(int spacingPx) { this(spacingPx, false, false); } public SpacingItemDecoration(int spacingPx, boolean addStartSpacing, boolean addEndSpacing) { this.spacingPx = spacingPx; this.addStartSpacing = addStartSpacing; this.addEndSpacing = addEndSpacing; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if (spacingPx <= 0) { return; } if (addStartSpacing && parent.getChildLayoutPosition(view) < 1 || parent.getChildLayoutPosition(view) >= 1) { if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { outRect.top = spacingPx; } else { outRect.left = spacingPx; } } if (addEndSpacing && parent.getChildAdapterPosition(view) == getTotalItemCount(parent) - 1) { if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { outRect.bottom = spacingPx; } else { outRect.right = spacingPx; } } } private int getTotalItemCount(RecyclerView parent) { return parent.getAdapter().getItemCount(); } private int getOrientation(RecyclerView parent) { if (parent.getLayoutManager() instanceof LinearLayoutManager) { return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation(); } else { throw new IllegalStateException("SpacingItemDecoration can only be used with a LinearLayoutManager."); } } } 

The RecyclerView is a bit different from the ListView . Actually, the RecyclerView needs a ListView like structure in it. For example, a LinearLayout . The LinearLayout has parameters for the dividing each element. In the code below I have a RecyclerView comprised of CardView objects within a LinearLayout with a "padding" that will put some space between items. Make that space really small and you get a line.

Here's the Recycler view in recyclerview_layout.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".ToDoList"> <!-- A RecyclerView with some commonly used attributes --> <android.support.v7.widget.RecyclerView android:id="@+id/todo_recycler_view" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout> 

And here is what each item looks like (and it shows as divided due to the android:padding in the LinearLayout that surrounds everything.) in another file: cards_layout.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="match_parent" **android:padding="@dimen/activity_vertical_margin"**> <!-- A CardView that contains a TextView --> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_gravity="center" android:layout_width="match_parent" android:layout_height="100dp" android:elevation="30dp" card_view:cardElevation="3dp"> <TextView android:id="@+id/info_text" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v7.widget.CardView> </LinearLayout> 

Too Late but for GridLayoutManager I use this:

 public class GridSpacesItemDecoration : RecyclerView.ItemDecoration { private int space; public GridSpacesItemDecoration(int space) { this.space = space; } public override void GetItemOffsets(Android.Graphics.Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { var position = parent.GetChildLayoutPosition(view); /// Only for GridLayoutManager Layouts var manager = parent.GetLayoutManager() as GridLayoutManager; if (parent.GetChildLayoutPosition(view) < manager.SpanCount) outRect.Top = space; if (position % 2 != 0) { outRect.Right = space; } outRect.Left = space; outRect.Bottom = space; } } 

This work for any span count you have.

Ollie.

I have a very simple way of adding a divider in RecyclerView. Use a custom adapter to modify the recycler view layout and then along with the recycler view items add LinearLayout with a background color (which will be the divider color) and add a height of 1dp (or as per your requirement) and width to match parent.

Here is a sample code.

 <?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="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="18dp"> <TextView android:id="@+id/list_row_SNO" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight=".8" android:layout_gravity="end" android:text="44." android:textAlignment="center" android:textSize="24sp" android:textColor="@color/colorBlack" android:fontFamily="sans-serif-condensed" /> <TextView android:id="@+id/list_row_Heading" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight=".2" android:layout_gravity="start" android:text="Student's application for leave and this what" android:textAlignment="textStart" android:textSize="24sp" android:textColor="@color/colorBlack" android:fontFamily="sans-serif-condensed" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/colorHighlight"> </LinearLayout> 1 <?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="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="18dp"> <TextView android:id="@+id/list_row_SNO" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight=".8" android:layout_gravity="end" android:text="44." android:textAlignment="center" android:textSize="24sp" android:textColor="@color/colorBlack" android:fontFamily="sans-serif-condensed" /> <TextView android:id="@+id/list_row_Heading" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight=".2" android:layout_gravity="start" android:text="Student's application for leave and this what" android:textAlignment="textStart" android:textSize="24sp" android:textColor="@color/colorBlack" android:fontFamily="sans-serif-condensed" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/colorHighlight"> </LinearLayout> 

 public class VerticalItemDecoration extends RecyclerView.ItemDecoration { private boolean verticalOrientation = true; private int space = 10; public VerticalItemDecoration(int value, boolean verticalOrientation) { this.space = value; this.verticalOrientation = verticalOrientation; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { //skip first item in the list if (parent.getChildAdapterPosition(view) != 0) { if (verticalOrientation) { outRect.set(space, 0, 0, 0); } else if (!verticalOrientation) { outRect.set(0, space, 0, 0); } } } } 

 mCompletedShippingRecyclerView.addItemDecoration(new VerticalItemDecoration(20,false)); 

Here's my lazy approach but it works: wrap the CardView in a layout and set a padding/margin on the parent layout to mimic the divider, and force the normal divider to null

list_item.xml

 <LinearLayout android:id="@+id/entry_item_layout_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingBottom="<divider_size>" > // this is the divider <CardView android:layout_width="<width_size>" android:layout_height="<height_size>"> ... </CardView> </LinearLayout 

list.xml

 <RecyclerView android:divider="@null" android:layout_width="<width_size>" android:layout_height="<height_size>" ... />