Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mobiRic/b3c275595f7f74b73178 to your computer and use it in GitHub Desktop.
Save mobiRic/b3c275595f7f74b73178 to your computer and use it in GitHub Desktop.
DividerItemDecoration. RecyclerView.ItemDecoration simple implementation

DividerItemDecoration

Simple RecyclerView ItemDecoration
Based on fatfingers implementation.

Fixed lapastillaroja implementation with correct first and last item handling.

Features

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

New in this fork

  • Can use resource id as drawable
  • SpaceItemDecoration if you need only empty space between items

Example

Default android divider

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

Custom divider as drawable (deprecated) with first divider (before first element) and last divider (after last element)

mCategoryRecyclerView.addItemDecoration(
        new DividerItemDecoration(getActivity().getDrawable(R.drawable.ic_launcher),
                true, true));

Custom divider as resource id

mCategoryRecyclerView.addItemDecoration(
        new DividerItemDecoration(getActivity(), R.drawable.ic_launcher,
                true, true));

Space divider

mCategoryRecyclerView.addItemDecoration(
        new SpaceItemDecoration(getActivity(), R.dimen.list_space,
                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.v4.content.ContextCompat;
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;
int mOrientation = -1;
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(Context context, int resId) {
mDivider = ContextCompat.getDrawable(context, resId);
}
public DividerItemDecoration(Context context, int resId, boolean showFirstDivider,
boolean showLastDivider) {
this(context, resId);
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;
}
int position = parent.getChildAdapterPosition(view);
if (position == RecyclerView.NO_POSITION || (position == 0 && !mShowFirstDivider)) {
return;
}
if (mOrientation == -1)
getOrientation(parent);
if (mOrientation == LinearLayoutManager.VERTICAL) {
outRect.top = mDivider.getIntrinsicHeight();
if (mShowLastDivider && position == (state.getItemCount() - 1)) {
outRect.bottom = outRect.top;
}
} else {
outRect.left = mDivider.getIntrinsicWidth();
if (mShowLastDivider && position == (state.getItemCount() - 1)) {
outRect.right = outRect.left;
}
}
}
@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 = mOrientation != -1 ? mOrientation : 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 - size;
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);
if (parent.getChildAdapterPosition(child) == (state.getItemCount() - 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 (mOrientation == -1) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
mOrientation = layoutManager.getOrientation();
} else {
throw new IllegalStateException(
"DividerItemDecoration can only be used with a LinearLayoutManager.");
}
}
return mOrientation;
}
}
import android.content.Context;
import android.graphics.Rect;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
public class SpaceItemDecoration extends RecyclerView.ItemDecoration
{
private final int mSpace;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;
int mOrientation = -1;
public SpaceItemDecoration(Context context, AttributeSet attrs) {
mSpace = 0;
}
public SpaceItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
boolean showLastDivider) {
this(context, attrs);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
public SpaceItemDecoration(int spaceInPx)
{
mSpace = spaceInPx;
}
public SpaceItemDecoration(int spaceInPx, boolean showFirstDivider,
boolean showLastDivider)
{
this(spaceInPx);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
public SpaceItemDecoration(Context ctx, int resId)
{
mSpace = ctx.getResources().getDimensionPixelSize(resId);
}
public SpaceItemDecoration(Context ctx, int resId, boolean showFirstDivider,
boolean showLastDivider)
{
this(ctx, resId);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state)
{
if (mSpace == 0) {
return;
}
if (mOrientation == -1)
getOrientation(parent);
int position = parent.getChildAdapterPosition(view);
if (position == RecyclerView.NO_POSITION || (position == 0 && !mShowFirstDivider)) {
return;
}
if (mOrientation == LinearLayoutManager.VERTICAL) {
outRect.top = mSpace;
if (mShowLastDivider && position == (state.getItemCount() - 1)) {
outRect.bottom = outRect.top;
}
} else {
outRect.left = mSpace;
if (mShowLastDivider && position == (state.getItemCount() - 1)) {
outRect.right = outRect.left;
}
}
}
private int getOrientation(RecyclerView parent) {
if (mOrientation == -1) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
mOrientation = layoutManager.getOrientation();
} else {
throw new IllegalStateException(
"DividerItemDecoration can only be used with a LinearLayoutManager.");
}
}
return mOrientation;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment