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
Copy link

ArthurSav commented Dec 10, 2014

Thanks, works great!

@zsiegel
Copy link

zsiegel 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
Copy link

franciscomagalhaes commented Dec 11, 2014

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

Thank you

@ravibhan90
Copy link

ravibhan90 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
Copy link

bilbo7833 commented Jan 27, 2015

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

@s1rius
Copy link

s1rius commented Mar 6, 2015

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

@nijandhan
Copy link

nijandhan 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
Copy link

yeongjoshua 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
Copy link

ceskobassman commented Jun 12, 2015

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

@zokipirlo
Copy link

zokipirlo commented Jul 30, 2015

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

@pratikbutani
Copy link

pratikbutani commented Oct 2, 2015

Use getChildAdapterPosition instead getChildPosition because getChildPosition is deprecated.

@Amarpreet88
Copy link

Amarpreet88 commented Jan 6, 2016

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

@hdavidzhu
Copy link

hdavidzhu commented Feb 9, 2016

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

@albertoha94
Copy link

albertoha94 commented Jun 23, 2016

Hey! Thanks for everything! Looking very good!

@ShaunLi
Copy link

ShaunLi commented Jul 12, 2016

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

@GaneshShetty951
Copy link

GaneshShetty951 commented May 8, 2017

it is good. thank you buddy

@sudheeshde
Copy link

sudheeshde commented Jun 15, 2017

Great.. Thanks dude....

@seyoung-hyun
Copy link

seyoung-hyun 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
Copy link

CoolMind 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