Skip to content

Instantly share code, notes, and snippets.

@lapastillaroja
Forked from akmalxxx/DividerItemDecoration.java
Last active November 17, 2023 23:06
Show Gist options
  • Save lapastillaroja/858caf1a82791b6c1a36 to your computer and use it in GitHub Desktop.
Save lapastillaroja/858caf1a82791b6c1a36 to your computer and use it in GitHub Desktop.
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

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

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

Thank you

@ravibhan90
Copy link

@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

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

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

@yeongjoshua
Copy link

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

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

@zokipirlo
Copy link

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

@pratikbutani
Copy link

Use getChildAdapterPosition instead getChildPosition because getChildPosition is deprecated.

@Amarpreet88
Copy link

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

@hdavidzhu
Copy link

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

@albertoha94
Copy link

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

it is good. thank you buddy

@sudheeshde
Copy link

Great.. Thanks dude....

@seyoung-hyun
Copy link

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

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