这是之前在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"/>

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


当前回答

下面是我在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 = spaceInDp
        outRect.right = spaceInDp
        outRect.bottom = spaceInDp
        // Add top margin only for the first item to avoid double space between items
        if (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))

其他回答

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

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

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

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

我从一个旧的要点中分叉了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()));

使用这个类在你的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;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view); // Item position
        int 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 edge
                outRect.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
            }
        }
    }
}

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

添加依赖关系:

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

添加到你的recyclerview:

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

这样就完成了!

这是我在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 = space
        outRect.bottom = space
    }
}

使用

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