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

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


当前回答

简单的方法是为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"/>

输出……

其他回答

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

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

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 ?: 0
        val position = parent.getChildAdapterPosition(view)
        val leading = if (position == 0) edgeSpacing else itemSpacing
        val trailing = if (position == count - 1) edgeSpacing else 0
        outRect.run {
            if ((parent.layoutManager as? LinearLayoutManager)?.orientation == LinearLayout.VERTICAL) {
                top = leading
                bottom = trailing
            } else {
                left = leading
                right = trailing
            }
        }
    }
}

用法:

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

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

        val recyclerView = rootView.findViewById<RecyclerView>(R.id.recycler_view)
        recyclerView.adapter = mListAdapter
        recyclerView.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)
        }

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

下面是我在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))

而不是创建一个形状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)