如何在Android RecyclerView中添加分隔线?

时间:2015-07-06 09:57:09

标签: android android-recyclerview material-design

我正在开发一个Android应用程序,我正在使用<script> var l = { firstName : "John", lastName : "Doe", age : 50, eyeColor : "blue" }; k = l; </script> 。我需要在RecyclerView中添加分隔符。 我试着添加 -

RecyclerView

下面是我的xml代码 -

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

23 个答案:

答案 0 :(得分:227)

在2016年10月的更新中,支持库v25.0.0现在具有基本水平和垂直分隔线的默认实现!

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

customLoader

答案 1 :(得分:208)

正确的方法是为ItemDecoration定义RecyclerView如下

<强> SimpleDividerItemDecoration.java

public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable mDivider;

    public SimpleDividerItemDecoration(Context context) {
        mDivider = context.getResources().getDrawable(R.drawable.line_divider);
    }

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

<强> 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="@color/dark_gray" />

</shape>

最后像这样设置

recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));

修改

@Alan Solitar指出

context.getResources().getDrawable(R.drawable.line_divider); 
折旧

而不是您可以使用

ContextCompat.getDrawable(context,R.drawable.line_divider);

答案 2 :(得分:32)

如果你想同时拥有水平和垂直分隔线:

  1. 定义水平&amp;垂直分隔线drawables:

    horizo​​ntal_divider.xml

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

    vertical_divider.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <size android:width="1dip" />
        <solid android:color="#22000000" />
    </shape>
    
  2. 在下面添加以下代码段:

    DividerItemDecoration verticalDecoration = new DividerItemDecoration(recyclerview.getContext(),
            DividerItemDecoration.HORIZONTAL);
    Drawable verticalDivider = ContextCompat.getDrawable(getActivity(), R.drawable.vertical_divider);
    verticalDecoration.setDrawable(verticalDivider);
    recyclerview.addItemDecoration(verticalDecoration);
    
    DividerItemDecoration horizontalDecoration = new DividerItemDecoration(recyclerview.getContext(),
            DividerItemDecoration.VERTICAL);
    Drawable horizontalDivider = ContextCompat.getDrawable(getActivity(), R.drawable.horizontal_divider);
    horizontalDecoration.setDrawable(horizontalDivider);
    recyclerview.addItemDecoration(horizontalDecoration);
    

答案 3 :(得分:27)

只需在项目适配器的末尾添加一个视图:

<View
 android:layout_width="match_parent"
 android:layout_height="1px"
 android:background="#FFFFFF"/>

更新:

要获得更好的结果,请将1px转换为1dp

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

答案 4 :(得分:24)

所有这些答案让我很接近,但他们每个人都错过了一个关键的细节。经过一番研究,我发现最简单的方法是将这三个步骤结合起来:

  1. 使用支持库的DividerItemDecoration
  2. 使用正确的颜色创建分隔符
  3. 在主题中将此分隔符设置为listDivider
  4. 第1步:配置RecyclerView

    recyclerView.addItemDecoration(
            new DividerItemDecoration(context, layoutManager.getOrientation()));
    

    第2步:在res / drawable / divider_gray.xml等文件中

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

    第3步:在应用主题中

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Other theme items above -->
        <item name="android:listDivider">@drawable/divider_gray</item>
    </style>
    

    编辑:更新以跳过上一个分隔符:
    使用了一下之后,我意识到它是在最后一项之后绘制一个分隔线,这很烦人。所以我按如下方式修改第1步以覆盖DividerItemDecoration中的默认行为(当然,另外一个选项是另一个选项):

    recyclerView.addItemDecoration(
            new DividerItemDecoration(context, layoutManager.getOrientation())) {
                @Override
                public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                    int position = parent.getChildAdapterPosition(view);
                    // hide the divider for the last child
                    if (position == parent.getAdapter().getItemCount() - 1) {
                        outRect.setEmpty();
                    } else {
                        super.getItemOffsets(outRect, view, parent, state);
                    }
                }
            }
    );
    

答案 5 :(得分:21)

以下是简单自定义分隔符的代码(垂直分隔符/ 1dp高度/黑色):

假设您有支持库:

compile "com.android.support:recyclerview-v7:25.1.1"

java代码

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

然后是custom_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>

答案 6 :(得分:8)

res / drawable 文件夹

中创建一个单独的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文件(your_file)连接到主要活动,如下所示:

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

答案 7 :(得分:8)

我认为您使用FragmentsRecyclerView

创建RecyclerViewLayoutManager对象

后,只需添加以下行
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
                DividerItemDecoration.VERTICAL);
        recyclerView.addItemDecoration(dividerItemDecoration);

多数民众赞成!

  

它支持HORIZONTAL和VERTICAL方向。

答案 8 :(得分:6)

所以这可能不是正确的方法,但我只是添加了一个视图到RecyclerView的单项视图(因为我认为没有内置函数),如下所示:

<View
    android:layout_width="fill_parent"
    android:layout_height="@dimen/activity_divider_line_margin"
    android:layout_alignParentBottom="true"
    android:background="@color/tasklist_menu_dividerline_grey" />

这意味着每个项目都有一条填充底部的线条。我用#111111背景做了大约1dp。这也给它带来了一种“3D”效果。

答案 9 :(得分:6)

试试这个简单的单行代码

recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),LinearLayoutManager.VERTICAL)); 

答案 10 :(得分:6)

您需要添加下一行......

mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));

答案 11 :(得分:5)

您可以创建一个简单的可重复使用的分隔符。

创建分隔符:

public class DividerItemDecorator extends RecyclerView.ItemDecoration {
    private Drawable mDivider;

    public DividerItemDecorator(Drawable divider) {
        mDivider = divider;
    }

    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int dividerLeft = parent.getPaddingLeft();
        int dividerRight = 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 dividerTop = child.getBottom() + params.bottomMargin;
            int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();

            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
            mDivider.draw(canvas);
        }
    }
}

创建分隔线: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="@color/grey_300" />
</shape>

将分隔符添加到您的Recyclerview:

RecyclerView.ItemDecoration dividerItemDecoration = new DividerItemDecorator(ContextCompat.getDrawable(context, R.drawable.divider));
recyclerView.addItemDecoration(dividerItemDecoration);

删除最后一项的分隔符:

要防止最后一项的分隔线绘制,您必须更改此行。

for (int i = 0; i < childCount; i++) 

for (int i = 0; i < childCount-1; i++)

您的最终实施应该是这样的:

public class DividerItemDecorator extends RecyclerView.ItemDecoration {
    private Drawable mDivider;

    public DividerItemDecorator(Drawable divider) {
        mDivider = divider;
    }

    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int dividerLeft = parent.getPaddingLeft();
        int dividerRight = parent.getWidth() - parent.getPaddingRight();

        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount - 1; i++) {
            View child = parent.getChildAt(i);

            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            int dividerTop = child.getBottom() + params.bottomMargin;
            int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();

            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
            mDivider.draw(canvas);
        }
    }
}

希望有所帮助:)

答案 12 :(得分:3)

yqritc的RecyclerView-FlexibleDivider使这个成为一个班轮。首先将其添加到您的build.gradle

compile 'com.yqritc:recyclerview-flexibledivider:1.4.0' // requires jcenter()

现在,您可以配置并添加设置recyclerView适配器的分隔符:

recyclerView.setAdapter(myAdapter);
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this).color(Color.RED).sizeResId(R.dimen.divider).marginResId(R.dimen.leftmargin, R.dimen.rightmargin).build());

答案 13 :(得分:2)

科特林版本:

recyclerview.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))

答案 14 :(得分:1)

不幸的是,Android让一些事情变得太复杂了。最简单的方法来实现你想要的,而不是在这里实现DividerItemDecoration:

将RecyclerView的背景颜色添加到所需的分色器颜色:

<RecyclerView
    android:id="@+id/rvList"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@color/colorLightGray"
    android:scrollbars="vertical"
    tools:listitem="@layout/list_item"
    android:background="@android:color/darker_gray"/>

将下边距(android:layout_marginBottom)添加到项目的布局根目录(list_item.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:layout_marginBottom="1dp">

    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="John Doe" />

    <TextView
        android:id="@+id/tvDescription"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvName"
        android:text="Some description blah blah" />

</RelativeLayout>

这应该在物品和RecyclerView的背景颜色之间留出1dp空间(深灰色将显示为分隔符)。

答案 15 :(得分:1)

只需在RecycleView Adapter的项目底部添加x金额的保证金。

<强> onCreateViewHolder

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

layoutParams.setMargins(0, 0, 0, 5);
itemView.setLayoutParams(layoutParams);

答案 16 :(得分:1)

为了使N J的答案更简单,你可以做到:

public class DividerColorItemDecoration extends DividerItemDecoration {

    public DividerColorItemDecoration(Context context, int orientation) {
        super(context, orientation);
        setDrawable(ContextCompat.getDrawable(context, R.drawable.line_divider));
    }
}

答案 17 :(得分:1)

recyclerview.addItemDecoration(new DividerItemDecoration(this, 0));

0为水平,1为Veritical

答案 18 :(得分:1)

我如何处理Divider视图以及Divider插图的方法是添加RecyclerView扩展。

1。

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

RecyclerViewExtension.kt

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

/*
* RecyclerViewExtension.kt
* */
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DividerItemDecoration
import 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的Activity或Fragment上,您可以通过调用以下命令来设置自定义可绘制对象:

recyclerView.setDivider(R.drawable.recycler_view_divider)

4。

干杯?

RecyclerView row with divider.

答案 19 :(得分:1)

我认为这是最简单的方法

mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
                DividerItemDecoration.VERTICAL);
// or DividerItemDecoration.HORIZONTALL
        mDividerItemDecoration.setDrawable(getDrawable(R.drawable.myshape));
        recyclerView.addItemDecoration(mDividerItemDecoration);

请注意::myshape可以是矩形,其高度要用作分隔线

答案 20 :(得分:0)

  class ItemOffsetDecoration(
        context: Context,
        private val paddingLeft: Int,
        private val paddingRight: Int
    ) : RecyclerView.ItemDecoration() {
        private var mDivider: Drawable? = null

        init {
            mDivider = ContextCompat.getDrawable(context, R.drawable.divider_medium)
        }

        override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
            val left = parent.paddingLeft + paddingLeft
            val right = parent.width - parent.paddingRight - paddingRight
            val childCount = parent.childCount
            for (i in 0 until childCount) {
                val child = parent.getChildAt(i)
                val params = child.layoutParams as RecyclerView.LayoutParams
                val top = child.bottom + params.bottomMargin
                val bottom = top + (mDivider?.intrinsicHeight ?: 0)

                mDivider?.let {
                    it.setBounds(left, top, right, bottom)
                    it.draw(c)
                }
            }
        }
    }

您只需要在R.drawable.divider_medium中指定颜色

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

</shape>

并将其添加到您的recyclerView

recyclerView.addItemDecoration(
                        ItemOffsetDecoration(
                            this,
                            resources.getDimension(resources.getDimension(R.dimen.dp_70).roundToInt()).roundToInt(),
                            0
                        )
                    )

引荐this

答案 21 :(得分:0)

Bhuvanesh BS解决方案有效。 Kotlin版本:

import android.graphics.Canvas
import android.graphics.drawable.Drawable
import androidx.recyclerview.widget.RecyclerView

class DividerItemDecorator(private val mDivider: Drawable?) : RecyclerView.ItemDecoration() {

    override fun onDraw(
        canvas: Canvas,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {

        val dividerLeft = parent.paddingLeft
        val dividerRight = parent.width - parent.paddingRight
        for (i in 0 until parent.childCount - 1) {
            val child = parent.getChildAt(i)
            val dividerTop =
                child.bottom + (child.layoutParams as RecyclerView.LayoutParams).bottomMargin
            val dividerBottom = dividerTop + mDivider!!.intrinsicHeight
            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom)
            mDivider.draw(canvas)
        }
    }
}

答案 22 :(得分:0)

好的,如果不需要更改分隔线的颜色,只需将alpha应用于分隔线装饰即可。

具有透明度的GridLayoutManager示例:

DividerItemDecoration horizontalDividerItemDecoration = new DividerItemDecoration(WishListActivity.this,
                DividerItemDecoration.HORIZONTAL);
        horizontalDividerItemDecoration.getDrawable().setAlpha(50);
        DividerItemDecoration verticalDividerItemDecoration = new DividerItemDecoration(WishListActivity.this,
                DividerItemDecoration.VERTICAL);
        verticalDividerItemDecoration.getDrawable().setAlpha(50);
        my_recycler.addItemDecoration(horizontalDividerItemDecoration);
        my_recycler.addItemDecoration(verticalDividerItemDecoration);

您仍然可以仅通过设置颜色来更改分隔线的颜色 对其进行过滤。

通过设置色调的GridLayoutManager示例:

DividerItemDecoration horizontalDividerItemDecoration = new DividerItemDecoration(WishListActivity.this,
                DividerItemDecoration.HORIZONTAL);
        horizontalDividerItemDecoration.getDrawable().setTint(getResources().getColor(R.color.colorAccent));
        DividerItemDecoration verticalDividerItemDecoration = new DividerItemDecoration(WishListActivity.this,
                DividerItemDecoration.VERTICAL);
        verticalDividerItemDecoration.getDrawable().setAlpha(50);
        my_recycler.addItemDecoration(horizontalDividerItemDecoration);
        my_recycler.addItemDecoration(verticalDividerItemDecoration);

此外,您还可以尝试设置滤色片,

 horizontalDividerItemDecoration.getDrawable().setColorFilter(colorFilter);