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