Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
DividerItemDecoration. RecyclerView.ItemDecoration simple implementation

DividerItemDecoration

Simple RecyclerView ItemDecoration
Based on fatfingers implementation.

Features

  • Can use any drawable as divider
  • Divider visible also at the beginning and end of the item's list (disable by deffault)
  • Only works with LinearLayoutManager

Example

Default android divider

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

Custom divider with first also end and last dividers

mCategoryRecyclerView.addItemDecoration(
        new DividerItemDecoration(getActivity().getDrawable(R.drawable.ic_launcher),
                true, true));
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;
}
@Override
public 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();
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mDivider == null) {
super.onDrawOver(c, parent, state);
return;
}
// Initialization needed to avoid compiler warning
int 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 { //horizontal
size = 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 { //horizontal
left = child.getLeft() - params.leftMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
// show last divider
if (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 { // horizontal
left = 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.");
}
}
}
@ArthurSav

This comment has been minimized.

Copy link

commented Dec 10, 2014

Thanks, works great!

@zsiegel

This comment has been minimized.

Copy link

commented Dec 10, 2014

From what I can see this does not show a divider in the last position since you are not accounting for it in the getItemOffsets method.

Unfortunately there is no way to tell if we are at the very last item since the RecyclerView only returns the current number of items on screen.

@franciscomagalhaes

This comment has been minimized.

Copy link

commented Dec 11, 2014

Great work, but how can I set the divider height?

Thank you

@ravibhan90

This comment has been minimized.

Copy link

commented Dec 12, 2014

@franciscomagalhaes

You can create a shape file with giving only one dimension in size depending on the orientation of recycler view . This way you can alter divider height or widht without changing the class code.

I used the below code for recycler view with horizontal scrolling.

@bilbo7833

This comment has been minimized.

Copy link

commented Jan 27, 2015

Unfortunately, I get a double divider in between two rows of the RecyclerView

@s1rius

This comment has been minimized.

Copy link

commented Mar 6, 2015

I comment out 50-52 lines, then "Show first divider" work.
How to show the last divider?

@nijandhan

This comment has been minimized.

Copy link

commented May 6, 2015

If i insert new item to top of the recycler view , there is no divider showing between first and second item.

@yeongjoshua

This comment has been minimized.

Copy link

commented May 22, 2015

Please edit
line 88: top = child.getTop() - params.topMargin - mDivider.getIntrinsicHeight();
line 91: left = child.getLeft() - params.leftMargin - mDivider.getIntrinsicWidth();
if not the divider drawn above each item may overlap the content

@ceskobassman

This comment has been minimized.

Copy link

commented Jun 12, 2015

I've forked it and added support for reverseLayout option in LinearLayoutManager:
https://gist.github.com/ceskobassman/179a62e1be65c2275baf

@zokipirlo

This comment has been minimized.

Copy link

commented Jul 30, 2015

All reported problems in comments are fixed here:
https://gist.github.com/zokipirlo/82336d89249e05bba5aa

@pratikbutani

This comment has been minimized.

Copy link

commented Oct 2, 2015

Use getChildAdapterPosition instead getChildPosition because getChildPosition is deprecated.

@Amarpreet88

This comment has been minimized.

Copy link

commented Jan 6, 2016

How to set left or right margin for the divider? Is there any way out?

@hdavidzhu

This comment has been minimized.

Copy link

commented Feb 9, 2016

When I toggle between different items, the last divider always redraws itself. Is this a bug?

@albertoha94

This comment has been minimized.

Copy link

commented Jun 23, 2016

Hey! Thanks for everything! Looking very good!

@ShaunLi

This comment has been minimized.

Copy link

commented Jul 12, 2016

I get a double divider in between two rows of the RecyclerView

@GaneshShetty951

This comment has been minimized.

Copy link

commented May 8, 2017

it is good. thank you buddy

@sudheeshde

This comment has been minimized.

Copy link

commented Jun 15, 2017

Great.. Thanks dude....

@seyoung-hyun

This comment has been minimized.

Copy link

commented Oct 1, 2018

Thanks for your code!

Can you let me know which license is used for distribution of this code?
I'd like to use this code for a commercial app so I need to check the license.

Happy coding! :)

@CoolMind

This comment has been minimized.

Copy link

commented Jan 24, 2019

Strange, but it adds additional spaces of the same width between items (so instead of 5 dp I have 10 dp width space). See another example in https://gist.github.com/johnwatsondev/720730cf6b8c59fa6abe4f31dbaf59d7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.