How can a divider line be added in an Android RecyclerView?

AndroidAndroid RecyclerviewMaterial Design

Android Problem Overview


I am developing an android application where I am using RecyclerView. I need to add a divider in RecyclerView. I tried to add -

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

below is my xml code -

   <android.support.v7.widget.RecyclerView
    android:id="@+id/drawerList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="15dp"
    />

Android Solutions


Solution 1 - Android

In the October 2016 update, the support library v25.0.0 now has a default implementation of basic horizontal and vertical dividers available!

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

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

Solution 2 - Android

The Right way is to define ItemDecoration for the RecyclerView is as following

SimpleDividerItemDecoration.java

public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable mDivider;
 
    public SimpleDividerItemDecoration(Context context) {
        mDivider = ContextCompat.getDrawable(context, 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);
        }
    }
}

Or If you are using kotlin: SimpleDividerItemDecoration.kt

class SimpleDividerItemDecoration(context: Context, @DrawableRes dividerRes: Int) : ItemDecoration() {

    private val mDivider: Drawable = ContextCompat.getDrawable(context, dividerRes)!!

    override fun onDrawOver(c: Canvas, parent: RecyclerView) {
        val left = parent.paddingLeft
        val right = parent.width - parent.paddingRight
        val childCount = parent.childCount
        for (i in 0 until childCount) {
            val child: View = parent.getChildAt(i)
            val params = child.layoutParams as RecyclerView.LayoutParams
            val top: Int = child.bottom + params.bottomMargin
            val bottom = top + mDivider.intrinsicHeight
            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>

Finally set it like this

recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));

Edit

As pointed by @Alan Solitar

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

is depreciated instead of that you can use

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

Solution 3 - Android

If you want to have both horizontal and vertical dividers:

  1. Define horizontal & vertical divider drawables:

###horizontal_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. Add this code segment below:

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

Solution 4 - Android

All of these answers got me close but they were each missing a key detail. After a bit of research, I found the easiest route to be a combination of these 3 steps:

  1. Use the support library's DividerItemDecoration
  2. Create a divider with the right color
  3. Set this divider in your theme as the listDivider

Step 1: while configuring RecyclerView

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

Step 2: in a file like 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>

Step 3: in the app's theme

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

EDIT: Updated to skip last divider:
After using this a bit, I realized it was drawing a divider after the last item, which was annoying. So I modified Step 1 as follows to override that default behavior in DividerItemDecoration (of course, making a separate class is another option):

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

Solution 5 - Android

Just add a View by the end of you item adapter:

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

Solution 6 - Android

Here is the code for a simple custom divider (vertical divider / 1dp height / black ):

It suppose you have Support Library:

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

java code

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

then the custom_divider.xml file sample :

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

Solution 7 - Android

Kotlin Version:

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

Solution 8 - Android

The way how I'm handling the Divider view and also Divider Insets is by adding a RecyclerView extension.

1.

Add a new extension file by naming View or RecyclerView:

RecyclerViewExtension.kt

and add the setDivider extension method inside the RecyclerViewExtension.kt file.

/*
* 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.

Create a Drawable resource file inside of drawable package like 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>

where you can specify the left and right margin on android:insetLeft and android:insetRight.

3.

On your Activity or Fragment where the RecyclerView is initialized, you can set the custom drawable by calling:

recyclerView.setDivider(R.drawable.recycler_view_divider)

4.

Cheers 

RecyclerView row with divider.

Solution 9 - Android

Create a seperate xml file in res/drawable folder

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

Connect that xml file (your_file) at the main activity, like this:

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

Solution 10 - Android

Try this simple single line code

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

Solution 11 - Android

I think you are using Fragments to have RecyclerView

Simply add these lines after creating your RecyclerView and LayoutManager Objects

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

Thats it!

> It supports both HORIZONTAL and VERTICAL orientations.

Solution 12 - Android

You need add next line...

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

Solution 13 - Android

So this might not be the correct way, but I just added a view to the single item view of the RecyclerView (as I don't think there is a built-in function) like so:

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

This means each item will have a line which fills it at its bottom. I made it about 1dp high with a #111111 background. This also gives it a kind of "3D" effect.

Solution 14 - Android

You can create a simple reusable divider.

Create Divider:

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

Create 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:width="1dp"
        android:height="1dp" />
    <solid android:color="@color/grey_300" />
</shape>

Add divider to your Recyclerview:

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

To remove divider for the last item:

To prevent divider drawing for the last item you have to change this line.

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

To

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

Your final implementation should be like this:

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

Hope it helps:)

Solution 15 - Android

Android just makes little things too complicated unfortunately. Easiest way to achieve what you want, without implementing DividerItemDecoration here:

Add background color to the RecyclerView to your desired divider color:

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

Add bottom margin (android:layout_marginBottom) to the layout root of the item (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>

This should give 1dp space between the items and the background color of RecyclerView (which is dark gray would appear as divider).

Solution 16 - Android

yqritc's RecyclerView-FlexibleDivider makes this a one liner. First add this to your build.gradle:

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

Now you can configure and add a divder where you set your recyclerView's adapter:

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

Solution 17 - Android

i think its the easiest way

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

Note that : myshape can be rectangel with height you want to make your divider

Solution 18 - Android

To make N J's answer a little simpler you can do:

public class DividerColorItemDecoration extends DividerItemDecoration {

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

Solution 19 - Android

Simply add a margin of x amount at the bottom of an item in your RecycleView Adapter.

onCreateViewHolder

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

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

Solution 20 - Android

recyclerview.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.HORIZONTAL));

for vertical line use LinearLayoutManager.VERTICAL

Solution 21 - Android

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

You just need to specify a color in 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>

and add it to your recyclerView

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

refernce this

Solution 22 - Android

KOTLIN - If you are looking for custom color divider between recycler view items, then here is the solution which works for me:

Step 1 : Give your recycler view a default item decoration. recyclerView.addItemDecoration(androidx.recyclerview.widget.DividerItemDecoration(activity, androidx.recyclerview.widget.LinearLayoutManager.VERTICAL))

Step 2 : Add a xml drawable specifying the size - width and height with the color you want.

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <size
        android:width="1dp"
        android:height="1dp" />
    <solid android:color="@color/your_color" />
</shape>

Step 3 : Add this line in your app theme.

<item name="android:listDivider">@drawable/your_drawable</item>

Solution 23 - Android

Bhuvanesh BS solution works. Kotlin version of this:

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

Solution 24 - Android

Alright, if don't need your divider color to be changed just apply alpha to the divider decorations.

Example for GridLayoutManager with transparency:

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

> You can still change the color of dividers by just setting color > filters to it.

Example for GridLayoutManager by setting tint:

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

Additionally you can also try setting color filter,

 horizontalDividerItemDecoration.getDrawable().setColorFilter(colorFilter);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionsofquestion 8View Question on Stackoverflow
Solution 1 - AndroidAditya Vyas-LakhanView Answer on Stackoverflow
Solution 2 - AndroidN JView Answer on Stackoverflow
Solution 3 - AndroidMohammed MukhtarView Answer on Stackoverflow
Solution 4 - AndroidgMaleView Answer on Stackoverflow
Solution 5 - AndroidLucas DiegoView Answer on Stackoverflow
Solution 6 - AndroidTobliugView Answer on Stackoverflow
Solution 7 - AndroidJavaView Answer on Stackoverflow
Solution 8 - AndroidGentView Answer on Stackoverflow
Solution 9 - AndroidAlexMView Answer on Stackoverflow
Solution 10 - AndroidPravin PerumalView Answer on Stackoverflow
Solution 11 - AndroidVivek MaruView Answer on Stackoverflow
Solution 12 - AndroidpablopatarcaView Answer on Stackoverflow
Solution 13 - AndroidSmashingView Answer on Stackoverflow
Solution 14 - AndroidBhuvanesh BSView Answer on Stackoverflow
Solution 15 - AndroidJohn GummadiView Answer on Stackoverflow
Solution 16 - AndroidGaurav VachhaniView Answer on Stackoverflow
Solution 17 - AndroidAbdelrahman HusseinView Answer on Stackoverflow
Solution 18 - AndroidWill PoitrasView Answer on Stackoverflow
Solution 19 - AndroidS SathiyaView Answer on Stackoverflow
Solution 20 - AndroidFreny ChristianView Answer on Stackoverflow
Solution 21 - AndroidAbhay PratapView Answer on Stackoverflow
Solution 22 - AndroidNandita GandhiView Answer on Stackoverflow
Solution 23 - AndroidBestUserAppsView Answer on Stackoverflow
Solution 24 - AndroidsanjeevView Answer on Stackoverflow