如何在RecyclerView中添加项目之间的分隔符和空格

这是之前在ListView类中使用分频器dividerHeight参数可以完成的一个示例:

<ListViewandroid: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.RecyclerViewandroid:id="@+id/activity_home_recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbars="vertical"/>

在这种情况下,是否可以定义边距和/或直接添加自定义分隔符视图到列表项的布局中,或者是否有更好的方法来实现我的目标?

788220 次浏览
我想让你注意一下Alex Fu在GitHub上的这个特定文件:# 0 < / p >

它是直接从支持演示中提取的diveritemdecoration .java示例文件。

在我的项目中导入这个文件后,我能够很好地获得分隔线,并将其作为项目装饰添加到回收器视图。

下面是我的onCreateView在我的片段中包含Recyclerview的样子:

@Overridepublic 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));
mRecyclerView.setHasFixedSize(true);mLayoutManager = new LinearLayoutManager(getActivity());mRecyclerView.setLayoutManager(mLayoutManager);mRecyclerView.setItemAnimator(new DefaultItemAnimator());
return rootView;}

我确信可以做额外的造型,但这只是一个起点。:)

2016年10月更新

Android支持库25.0.0版本引入了# 0类:

DividerItemDecoration是一个RecyclerView。物品装饰,可以用作LinearLayoutManager物品之间的分隔符。它同时支持HORIZONTALVERTICAL方向。

用法:

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

以前的回答

有些答案使用的方法已经过时,或者没有给出完整的解决方案,所以我试着做一个简短的、最新的总结。


ListView不同,RecyclerView类没有任何与分隔符相关的参数。相反,你需要扩展#2,一个RecyclerView的内部类:

ItemDecoration允许应用程序向适配器数据集中的特定项视图添加特殊的绘图和布局偏移量。这可以用于在项目之间绘制分隔线,高光,视觉分组边界等。

所有ItemDecorations都按照它们被添加的顺序绘制,在项目视图之前(在onDraw()中)和在项目之后(在onDrawOver中(CanvasRecyclerViewRecyclerView.State))。

Vertical空格ItemDecoration

扩展ItemDecoration,添加一个自定义构造函数,将空格height作为参数,并覆盖getItemOffsets()方法:

public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration {
private final int verticalSpaceHeight;
public VerticalSpaceItemDecoration(int verticalSpaceHeight) {this.verticalSpaceHeight = verticalSpaceHeight;}
@Overridepublic 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.topoutRect.leftoutRect.right属性以获得所需的效果。

分频器# 0

扩展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);}
@Overridepublic 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的构造函数,例如可拉的/ 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()方法。

使用

要使用你的新类,添加VerticalSpaceItemDecorationDividerSpaceItemDecorationRecyclerView,例如在fragment的onCreateView()方法中:

private static final int VERTICAL_ITEM_SPACE = 48;private RecyclerView recyclerView;private LinearLayoutManager linearLayoutManager;@Overridepublic 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 ItemDecorationrecyclerView.addItemDecoration(new VerticalSpaceItemDecoration(VERTICAL_ITEM_SPACE));//orrecyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));//orrecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), R.drawable.divider));
recyclerView.setAdapter(...);
return rootView;}

还有卢卡斯·罗查的图书馆是为了简化道具装饰过程。不过我还没试过。

排名0的有:

  • 收藏的库存项目装饰,包括:
  • 项目间距水平/垂直分隔。
  • 列表项

这实际上并不能解决问题,但是作为一种临时的解决方法,您可以在XML布局中设置卡片上的useCompatPadding属性,使其与在前lollipop版本上测量的相同。

card_view:cardUseCompatPadding="true"

一个简单的ItemDecoration实现,所有项目之间的空间相等:

public class SpacesItemDecoration extends RecyclerView.ItemDecoration {private int space;
public SpacesItemDecoration(int space) {this.space = space;}
@Overridepublic 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 itemsif(parent.getChildAdapterPosition(view) == 0) {outRect.top = space;}}}

为视图添加边距。这对我很管用。

android:layout_marginTop="10dp"

如果你只想添加相等的间距,而想在XML中执行,只需将padding设置为RecyclerView,将等量的layoutMargin设置为您膨胀到RecyclerView的项目,并让背景颜色决定间距颜色。

从谷歌搜索,添加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;}
@Overridepublic 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();}}
@Overridepublic void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {if (mDivider == null) {super.onDrawOver(c, parent, state);return;}
// Initialization needed to avoid compiler warningint 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 { // Horizontalsize = 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 { // Horizontalleft = child.getLeft() - params.leftMargin;right = left + size;}mDivider.setBounds(left, top, right, bottom);mDivider.draw(c);}
// Show the last dividerif (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 { // hHorizontalleft = 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.");}}}

因为我已经设置ItemAnimatorsItemDecorator不会随着动画的进入或退出。

我只是在我的项目视图布局文件中为每个项目设置了一个视图行。它解决了我的案子。对于一个简单的分割器来说,DividerItemDecoration感觉魔法太多了。

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

我认为使用一个简单的分隔器会对你有帮助

为每个项目添加分隔符:

1. 将此添加到可绘制目录line_divider.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><sizeandroid: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中添加以下内容:

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

4. 添加项目之间的间距

你只需要添加padding属性到你的项目视图

<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>

对于那些只在RecyclerView中寻找项目之间的空格的人,看看我的方法,在所有项目之间获得相等的空间,除了第一项和最后一项,我给了更大的填充。我只应用填充左/右在水平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);}
@Overridepublic 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.");}}}

文件# 0

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

如果你想为物品添加相同的空间,最简单的方法是为RecycleView添加顶部+左侧填充,为卡片物品添加右侧+底部空白。

文件# 0

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

文件# 0

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

文件# 0

<RecyclerViewandroid:paddingLeft="@dimen/divider"android:paddingTop="@dimen/divider"/>
下面是我的偷懒方法,但它很有效:将CardView包装在一个布局中,并在父布局上设置一个填充/边距来模拟分隔符,并强制普通分隔符为null

文件# 0

<LinearLayoutandroid: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<CardViewandroid:layout_width="<width_size>"android:layout_height="<height_size>">...</CardView></LinearLayout

文件# 0

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

实现它自己的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;}
@Overridepublic 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.");}}}

简单的方法是为RecyclerView设置背景色,并为项目设置不同的背景色。这里有一个例子……

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

TextView条目(它可以是任何东西)底部边距“;x"Dp或者px。

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

输出……

Enter image description here

0和1有点不同。实际上,RecyclerView需要一个类似ListView的结构。例如,LinearLayoutLinearLayout有用于划分每个元素的参数。

在下面的代码中,我有一个由CardView对象组成的RecyclerView,在LinearLayout中带有“;填充”;这样可以在项目之间留出一些空间。把空间缩小,就能得到一条线。

下面是文件recyclerview_layout.xml中的Recycler视图:

<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.RecyclerViewandroid:id="@+id/todo_recycler_view"android:scrollbars="vertical"android:layout_width="match_parent"android:layout_height="match_parent"/>
</RelativeLayout>

这里是每个项目看起来像(它显示为分割由于android:填充在线性布局中,围绕一切)在另一个文件: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.CardViewxmlns: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"><TextViewandroid:id="@+id/info_text"android:layout_width="match_parent"android:layout_height="match_parent"/></android.support.v7.widget.CardView></LinearLayout>
  • 下面是一个添加分隔符的简单方法

  • 只需添加一个背景到你的回收项目的布局如下

      <?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">
    <ImageViewandroid:id="@+id/imageViewContactLogo"android:layout_width="60dp"android:layout_height="60dp"android:layout_marginRight="10dp"android:src="@drawable/ic_user" />
    <LinearLayoutandroid: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">
    <TextViewandroid: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" />
    <TextViewandroid: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>
    <TextViewandroid: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" />
    <Buttonandroid:id="@+id/buttonInvite"android:layout_width="54dp"android:layout_height="wrap_content"android:background="@drawable/ic_add_friend" /></LinearLayout>

在drawable文件夹中创建以下shape_border.xml文件:

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

这是最终的结果-一个带分隔符的RecyclerView。

这是最终的结果-一个RecyclerView与分隔器。 < / >

我从一个旧的要点中分叉了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.}}
@Overridepublic 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();elsethrow new IllegalArgumentException("Only usable with vertical lists");}
@Overridepublic 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()));

这个链接对我来说很有吸引力:

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;}
@Overridepublic 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();}}
@Overridepublic void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {if (mDivider == null) {super.onDrawOver(c, parent, state);return;}
// Initialization needed to avoid compiler warningint 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 { //horizontalsize = 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 { //horizontalleft = child.getLeft() - params.leftMargin;right = left + size;}mDivider.setBounds(left, top, right, bottom);mDivider.draw(c);}
// show last dividerif (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 { // horizontalleft = 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.");}}}

然后在你的活动中:

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

或者如果你使用片段:

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

我们可以使用附加到recyclerview的各种装饰器来装饰物品,例如:

简单地使用下面的…摘自答案是yes clear:

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);}
@Overridepublic 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);

这将在列表中的每个项目之间显示分隔符,如下所示:

Enter image description here

对于那些想了解更多细节的人,可以看看这篇指南使用recyclerview_ CodePath Android Cliffnotes

这里的一些答案建议使用边距,但问题是:

如果你同时添加了上边距和下边距,它们将在项目之间显示为添加的,而且它们将太大。如果只添加其中之一,则整个列表的顶部或底部都没有边距。如果你在上面加上一半的距离,在下面加上一半的距离,外层的边缘就太小了。

因此,唯一美观上正确的解决方案是系统知道在哪里正确应用的分隔符:项目之间,但不是项目的上面或下面。

由于没有正确的方法来实现这一点,但正确使用材料设计,我只是做了以下技巧,直接在列表项上添加一个分隔符:

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

我在列表中添加了一行,如下所示:

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

“1 px"会画一条细线。

如果你想隐藏最后一行的分隔符,那么在最后一个列表项的onBindViewHolder上使用divider.setVisiblity(View.GONE);

一个非常简单的解决方案是使用RecyclerView-FlexibleDivider

添加依赖关系:

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

添加到你的recyclerview:

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

这样就完成了!

RecyclerView没有提供一个简单的界面来绘制列表的分隔符。但实际上它为我们提供了更灵活的

我们使用RecyclerView。ItemDecoration来装饰RecyclerView的瓷砖与分隔或任何你想要的。这也是为什么它被称为ItemDecoration。

如第0条所述:

分隔符位于贴图的基线内。

.

所以如果你想遵循材料设计指南,你不需要额外的空间来画分隔线。把它们画在瓷砖上。然而,你有权利做任何你想做的事。所以我实现了一个让你能够设置嵌入以及在瓷砖上/下面绘制的功能。

public class InsetDivider extends RecyclerView.ItemDecoration {
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Paint mPaint;// in pixelprivate int mDividerHeight;// left inset for vertical list, top inset for horizontal listprivate int mFirstInset;// right inset for vertical list, bottom inset for horizontal listprivate int mSecondInset;private int mColor;private int mOrientation;// set it to true to draw divider on the tile, or false to draw beside the tile.// if you set it to false and have inset at the same time, you may see the background of// the parent of RecyclerView.private boolean mOverlay;
private InsetDivider() {mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setStyle(Paint.Style.FILL);}
public int getDividerHeight() {return mDividerHeight;}
public void setDividerHeight(int dividerHeight) {this.mDividerHeight = dividerHeight;}
public int getFirstInset() {return mFirstInset;}
public void setFirstInset(int firstInset) {this.mFirstInset = firstInset;}
public int getSecondInset() {return mSecondInset;}
public void setSecondInset(int secondInset) {this.mSecondInset = secondInset;}
public int getColor() {return mColor;}
public void setColor(int color) {this.mColor = color;mPaint.setColor(color);}
public int getOrientation() {return mOrientation;}
public void setOrientation(int orientation) {this.mOrientation = orientation;}
public boolean getOverlay() {return mOverlay;}
public void setOverlay(boolean overlay) {this.mOverlay = overlay;}
@Overridepublic void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {if (mOrientation == VERTICAL_LIST) {drawVertical(c, parent);} else {drawHorizontal(c, parent);}}
protected void drawVertical(Canvas c, RecyclerView parent) {final int left = parent.getPaddingLeft() + mFirstInset;final int right = parent.getWidth() - parent.getPaddingRight() - mSecondInset;final int childCount = parent.getChildCount();for (int i = 0; i < childCount; i++) {final View child = parent.getChildAt(i);if (parent.getChildAdapterPosition(child) == (parent.getAdapter().getItemCount() - 1)) {continue;}final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();final int bottom;final int top;if (mOverlay) {bottom = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));top = bottom - mDividerHeight;} else {top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));bottom = top + mDividerHeight;}c.drawRect(left, top, right, bottom, mPaint);}}
protected void drawHorizontal(Canvas c, RecyclerView parent) {final int top = parent.getPaddingTop() + mFirstInset;final int bottom = parent.getHeight() - parent.getPaddingBottom() - mSecondInset;final int childCount = parent.getChildCount();for (int i = 0; i < childCount; i++) {final View child = parent.getChildAt(i);if (parent.getChildAdapterPosition(child) == (parent.getAdapter().getItemCount() - 1)) {continue;}final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();final int right;final int left;if (mOverlay) {right = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));left = right - mDividerHeight;} else {left = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));right = left + mDividerHeight;}c.drawRect(left, top, right, bottom, mPaint);}}
@Overridepublic void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {if (mOverlay) {super.getItemOffsets(outRect, view, parent, state);return;}
if (mOrientation == VERTICAL_LIST) {outRect.set(0, 0, 0, mDividerHeight);} else {outRect.set(0, 0, mDividerHeight, 0);}}
/*** Handy builder for creating {@link InsetDivider} instance.*/public static class Builder {
private Context mContext;private int mDividerHeight;private int mFirstInset;private int mSecondInset;private int mColor;private int mOrientation;private boolean mOverlay = true; // set default to true to follow Material Design Guidelines
public Builder(Context context) {mContext = context;}
public Builder dividerHeight(int dividerHeight) {mDividerHeight = dividerHeight;return this;}
public Builder insets(int firstInset, int secondInset) {mFirstInset = firstInset;mSecondInset = secondInset;return this;}
public Builder color(@ColorInt int color) {mColor = color;return this;}
public Builder orientation(int orientation) {mOrientation = orientation;return this;}
public Builder overlay(boolean overlay) {mOverlay = overlay;return this;}
public InsetDivider build() {InsetDivider insetDivider = new InsetDivider();
if (mDividerHeight == 0) {// Set default divider height to 1dp.insetDivider.setDividerHeight(mContext.getResources().getDimensionPixelSize(R.dimen.divider_height));} else if (mDividerHeight > 0) {insetDivider.setDividerHeight(mDividerHeight);} else {throw new IllegalArgumentException("Divider's height can't be negative.");}
insetDivider.setFirstInset(mFirstInset < 0 ? 0 : mFirstInset);insetDivider.setSecondInset(mSecondInset < 0 ? 0 : mSecondInset);
if (mColor == 0) {throw new IllegalArgumentException("Don't forget to set color");} else {insetDivider.setColor(mColor);}
if (mOrientation != InsetDivider.HORIZONTAL_LIST && mOrientation != InsetDivider.VERTICAL_LIST) {throw new IllegalArgumentException("Invalid orientation");} else {insetDivider.setOrientation(mOrientation);}
insetDivider.setOverlay(mOverlay);
return insetDivider;}}}

你可以这样使用它:

ItemDecoration divider = new InsetDivider.Builder(this).orientation(InsetDivider.VERTICAL_LIST).dividerHeight(getResources().getDimensionPixelSize(R.dimen.divider_height)).color(getResources().getColor(R.color.colorAccent)).insets(getResources().getDimensionPixelSize(R.dimen.divider_inset), 0).overlay(true).build();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);recyclerView.setLayoutManager(new LinearLayoutManager(this));recyclerView.addItemDecoration(divider);

我还写了一个关于如何实现ItemDecoration以及如何使用它们的演示应用程序。你可以查看我的GitHub仓库Dividers-For-RecyclerView。它有三个实现:

  • UnderneathDivider
  • OverlayDivider
  • InsetDivider

2016年10月更新

在v25.0.0支持库中,终于有了基本水平和垂直分隔符的默认实现!

DividerItemDecoration

只需添加

recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL));
你可能还需要添加依赖项
# 0 < / p >

为了自定义它,你可以添加一个自定义drawable:

DividerItemDecoration itemDecorator = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL);itemDecorator.setDrawable(ContextCompat.getDrawable(getContext(), 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>

对于GridLayoutManager,我使用这个:

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 Layoutsvar 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;}}

这适用于任何跨度。

您可以通过编程方式轻松地添加它。

如果你的布局管理器是线性布局,那么你可以使用:

DividerItemDecoration是一个RecyclerView。ItemDecoration即可以用作LinearLayoutManager项之间的分隔符。它支持水平和垂直方向。

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

Source .

    其中一种方法是同时使用cardview和recycler视图。我们可以很容易地添加一个效果,比如分隔线。例如:# 0 < / p >
  1. 另一种方法是通过添加一个视图作为回收器视图list_item_layout的分隔符。

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

我有一个非常简单的方法在RecyclerView中添加一个分隔符。使用自定义适配器修改回收器视图布局,然后与回收器视图项目一起添加带有背景色(将是分隔色)的线性布局,并添加1dp的高度(或根据您的要求)和宽度以匹配父级。

下面是一个示例代码。

<?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">
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:padding="18dp">
<TextViewandroid: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" />
<TextViewandroid: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>
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@color/colorHighlight"></LinearLayout>
</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;}
@Overridepublic void getItemOffsets(Rect outRect, View view, RecyclerView parent,RecyclerView.State state) {// Skip first item in the listif (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));
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;}
@Overridepublic 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);}}}}

这将增加每个项目的顶部和底部(或左右)的空间。然后你可以把它设置为recyclerView

recyclerView.addItemDecoration(new CommonItemSpaceDecoration(16));

文件# 0

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

如果有人只想在项目之间添加10dp间距,你可以通过设置一个drawable为DividerItemDecoration来实现:

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

其中divider_10dp是一个可绘制资源,包含:

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

使用这个类在RecyclerView中设置分隔符。

public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount;private int spacing;private boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {this.spanCount = spanCount;this.spacing = spacing;this.includeEdge = includeEdge;}
@Overridepublic void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {int position = parent.getChildAdapterPosition(view); // Item positionint column = position % spanCount; // Item column
if (includeEdge) {outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)
if (position < spanCount) { // Top edgeoutRect.top = spacing;}outRect.bottom = spacing; // Item bottom} else {outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing)if (position >= spanCount) {outRect.top = spacing; // Item top}}}}

只需在回收器视图对象的init之后添加这一行。

< >强片段:< / >强

mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(),android.R.drawable.divider_horizontal_bright));

活动<强> < / >强

mRecyclerView.addItemDecoration(new DividerItemDecoration(this,android.R.drawable.divider_horizontal_bright));

项目装饰

public class DividerItemDecoration extends RecyclerView.ItemDecoration {public static final int VERTICAL_LIST = 0;
public DividerItemDecoration(ListActivity listActivity, Object p1) {}
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);}
@Overridepublic 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);}}}

这很简单,你不需要这么复杂的代码:

DividerItemDecoration divider =new DividerItemDecoration(mRVMovieReview.getContext(),DividerItemDecoration.VERTICAL);
divider.setDrawable(ContextCompat.getDrawable(getBaseContext(),R.drawable.line_divider));
mRVMovieReview.addItemDecoration(divider);

在你的绘图中添加这个: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:height="1dp" /><solid android:color="@android:color/black" /></shape>

我觉得需要一个简单的、不使用XML的、基于代码的答案

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
ShapeDrawable shapeDrawableForDivider = new ShapeDrawable(new RectShape());
int dividerThickness = // (int) (SomeOtherView.getHeight() * desiredPercent);shapeDrawableForDivider.setIntrinsicHeight(dividerThickness);shapeDrawableForDivider.setAlpha(0);
dividerItemDecoration.setDrawable(shapeDrawableForDivider);
recyclerView.addItemDecoration(dividerItemDecoration);

我非常喜欢这个答案,我用Kotlin的单一表达式重新写了一遍:

    recyclerView.addItemDecoration(DividerItemDecoration(this,DividerItemDecoration.VERTICAL).also { deco ->with (ShapeDrawable(RectShape())){intrinsicHeight = (resources.displayMetrics.density * 24).toInt()alpha = 0deco.setDrawable(this)}})

这和@Nerdy最初的答案是一样的,只是它将分隔线的高度设置为24dp,而不是另一个视图高度的百分比。

•# 0

通过使用PrimeAdapter,处理RecyclerViews中的分隔符可以非常简单。它为创建和管理分隔器提供了多种功能和更大的灵活性。

您可以按照以下方式创建适配器(请参阅GitHub中关于使用的完整文档):

val adapter = PrimeAdapter.with(recyclerView).setLayoutManager(LinearLayoutManager(activity)).set().build(ActorAdapter::class.java)

创建适配器实例后,您可以简单地使用以下命令添加分隔符:

//----- Default divider:adapter.setDivider()
//----- Divider with a custom drawable:adapter.setDivider(ContextCompat.getDrawable(context, R.drawable.divider))
//----- Divider with a custom color:adapter.setDivider(Color.RED)
//----- Divider with a custom color and a custom inset:adapter.setDivider(Color.RED, insetLeft = 16, insetRight = 16)
//----- Deactivate dividers:adapter.setDivider(null)

Enter image description here

而不是创建一个shape xml来改变分割线的高度和颜色,你可以通过编程来创建它:

val divider = DividerItemDecoration(context,DividerItemDecoration.VERTICAL)
divider.setDrawable(ShapeDrawable().apply {intrinsicHeight = resources.getDimensionPixelOffset(R.dimen.dp_15)paint.color = Color.RED // Note://   Currently (support version 28.0.0), we//   can not use tranparent color here. If//   we use transparent, we still see a//   small divider line. So if we want//   to display transparent space, we//   can set color = background color//   or we can create a custom ItemDecoration//   instead of DividerItemDecoration.})
recycler_devices.addItemDecoration(divider)

我处理分隔器视图和分隔器Insets的方式是通过添加一个RecyclerView扩展。

1.

通过命名View或RecyclerView添加一个新的扩展文件:

RecyclerViewExtension.kt

并在RecyclerViewExtension中添加setDivider扩展方法。kt文件。

/** RecyclerViewExtension.kt* */import androidx.annotation.DrawableResimport androidx.core.content.ContextCompatimport androidx.recyclerview.widget.DividerItemDecorationimport androidx.recyclerview.widget.RecyclerView

fun RecyclerView.setDivider(@DrawableRes drawableRes: Int) {val divider = DividerItemDecoration(this.context,DividerItemDecoration.VERTICAL)val drawable = ContextCompat.getDrawable(this.context,drawableRes)drawable?.let {divider.setDrawable(it)addItemDecoration(divider)}}

2.

drawable包中创建一个Drawable资源文件,如recycler_view_divider.xml:

<inset xmlns:android="http://schemas.android.com/apk/res/android"android:insetLeft="10dp"android:insetRight="10dp">
<shape><size android:height="0.5dp" /><solid android:color="@android:color/darker_gray" /></shape>
</inset>

您可以在android:insetLeftandroid:insetRight上指定左保证金和右保证金

3.

在你的活动或片段中,RecyclerView被初始化,你可以通过调用:

recyclerView.setDivider(R.drawable.recycler_view_divider)

4.

欢呼声🍺

RecyclerView row with divider. < / >

下面是我在Kotlin中如何做的,在项目之间设置一个默认大小为10dp的简单空间:

class SimpleItemDecoration(context: Context, space: Int = 10) : RecyclerView.ItemDecoration() {
private val spaceInDp = ConvertUtil.dpToPx(context, space)
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
outRect.left = spaceInDpoutRect.right = spaceInDpoutRect.bottom = spaceInDp// Add top margin only for the first item to avoid double space between itemsif (parent.getChildAdapterPosition(view) == 0) {outRect.top = spaceInDp}}}

这是dpToPx方法:

fun dpToPx(context: Context, dp: Int): Int {return (dp * context.resources.displayMetrics.density).toInt()}

然后像这样将它添加到RecyclerView中:(感谢@MSpeed)

recyclerView.addItemDecoration(SimpleItemDecoration(context))

这是我在Kotlin中为列显示(网格)所做的

  class ItemDecorationColumns(private val space: Int) : ItemDecoration() {
override fun getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State) {val position = parent.getChildLayoutPosition(view)val manager = parent.layoutManager as GridLayoutManager?val spanCount = manager?.spanCount ?: 0
if (position < spanCount) {outRect.top = space}
if (position % 2 != 0) {outRect.right = space}outRect.left = spaceoutRect.bottom = space}}

使用

rvAlbums.addItemDecoration(ItemDecorationColumns(resources.getDimensionPixelSize(R.dimen.space)))

为了在RecylerView中实现项目之间的间隔,我们可以使用ItemDecorators:

addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State,) {super.getItemOffsets(outRect, view, parent, state)if (parent.getChildAdapterPosition(view) > 0) {outRect.top = 8.dp // Change this value with anything you want. Remember that you need to convert integers to pixels if you are working with dps :)}}})

对于我粘贴的代码,有几件事需要考虑:

  • 你其实不需要调用super.getItemOffsets,但我选择了,因为我想扩展基类定义的行为。如果库得到了在幕后执行更多逻辑的更新,我们就会错过它。

  • 除了向Rect添加顶部间距之外,还可以添加底部间距,但与获取适配器的最后一项相关的逻辑更复杂,因此这可能会稍微好一些。

  • 我使用一个扩展属性将一个简单的整数转换为dps: 8.dp。类似这样的方法可能有用:

val Int.dp: Intget() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
// Extension function works too, but invoking it would become something like 8.dp()

这里有一个装饰,可以让你设置项目之间的间距以及边缘的间距。这适用于HORIZONTALVERTICAL布局。

class LinearSpacingDecoration(@Px private val itemSpacing: Int,@Px private val edgeSpacing: Int = 0): RecyclerView.ItemDecoration() {override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {val count = parent.adapter?.itemCount ?: 0val position = parent.getChildAdapterPosition(view)val leading = if (position == 0) edgeSpacing else itemSpacingval trailing = if (position == count - 1) edgeSpacing else 0outRect.run {if ((parent.layoutManager as? LinearLayoutManager)?.orientation == LinearLayout.VERTICAL) {top = leadingbottom = trailing} else {left = leadingright = trailing}}}}

用法:

recyclerView.addItemDecoration(LinearSpacingDecoration(itemSpacing = 10, edgeSpacing = 20))

如果有人想为spaceBetween, paddingLeft, paddingTop, paddingRight和paddingBottom设置不同的值。

class ItemPaddingDecoration(private val spaceBetween: Int,private val paddingLeft: Int = spaceBetween,private val paddingTop: Int = spaceBetween,private val paddingRight: Int = spaceBetween,private val paddingBottom: Int = spaceBetween) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {val position = parent.getChildAdapterPosition(view)val orientation = when (val layoutManager = parent.layoutManager) {is LinearLayoutManager -> {layoutManager.orientation}is GridLayoutManager -> {layoutManager.orientation}else -> {RecyclerView.HORIZONTAL}}if (orientation == RecyclerView.HORIZONTAL) {when {position == 0 -> {outRect.set(paddingLeft, paddingTop, spaceBetween, paddingBottom)}position < parent.adapter!!.itemCount - 1 -> {outRect.set(0, paddingTop, spaceBetween, paddingBottom)}else -> {outRect.set(0, paddingTop, paddingRight, paddingBottom)}}} else {when {position == 0 -> {outRect.set(paddingLeft, paddingTop, paddingRight, paddingBottom)}position < parent.adapter!!.itemCount - 1 -> {outRect.set(paddingLeft, 0, paddingRight, spaceBetween)}else -> {outRect.set(paddingLeft, 0, paddingRight, paddingBottom)}}}}}

最新的方法是这一个,例如在Fragment的onCreateView中使用:

        val recyclerView = rootView.findViewById<RecyclerView>(R.id.recycler_view)recyclerView.adapter = mListAdapterrecyclerView.layoutManager = LinearLayoutManager(context)rootView.context.let {val dividerItemDecoration = MaterialDividerItemDecoration(it,MaterialDividerItemDecoration.VERTICAL)dividerItemDecoration.isLastItemDecorated = false
// https://github.com/material-components/material-components-android/blob/master/docs/components/Divider.md// Needed if you did not set colorOnSurface in your theme because otherwise the default color would be pink_900 -> default according to Material should be colorOnSurface (12% opacity applied automatically on top).//            dividerItemDecoration.setDividerColorResource(it, R.color.colorDivider)
recyclerView.addItemDecoration(dividerItemDecoration)}

我想你们可以忘记之前所有的解。

使用RecyclerView itemdecoration -一个基本的分隔符样本在Kotlin android

一个完整的示例,包括一个构建器,添加边缘或使用资源颜色的可能性

    class SeparatorDecoration constructor(ctx: Context, @ColorRes dividerColor: Int, heightDp: Float) :RecyclerView.ItemDecoration() {
private val mPaints = Paint()
init {mPaints.color = dividerColorval thickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,heightDp,ctx.resources.displayMetrics)mPaints.strokeWidth = thickness}
override fun getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State) {val params = view.layoutParams as RecyclerView.LayoutParams
// and add a separator to any view but the last oneval p = params.viewAdapterPosition
// and add a separator to any view but the last oneif (p < state.itemCount) outRect[0, 0, 0] =mPaints.strokeWidth.toInt() // left, top, right, bottomelse outRect.setEmpty() // 0, 0, 0, 0}
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
// we set the stroke width before, so as to correctly draw the line we have to offset by width / 2val offset = (mPaints.strokeWidth / 2).roundToInt()
// this will iterate over every visible viewfor (i in 0 until parent.childCount) {// get the viewval view: View = parent.getChildAt(i)val params = view.layoutParams as RecyclerView.LayoutParams
// get the positionval position = params.viewAdapterPosition
// and finally draw the separatorif (position < state.itemCount) {c.drawLine(view.left.toFloat(),(view.bottom + offset).toFloat(),view.right.toFloat(), (view.bottom + offset).toFloat(), mPaints)}}}}

设置很简单。只需将您的装饰与其余的初始设置一起添加到您的recyclerView。

 val decoration = SeparatorDecoration(context, R.color.primaryColor, 1.5f)recyclerview.addItemDecoration(decoration)