-
Star
(170)
You must be signed in to star a gist -
Fork
(23)
You must be signed in to fork a gist
-
-
Save lapastillaroja/858caf1a82791b6c1a36 to your computer and use it in GitHub Desktop.
# DividerItemDecoration | |
Simple RecyclerView ItemDecoration | |
Based on [fatfingers](https://gist.github.com/fatfingers/233abbae200b5e87297b) 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 | |
```java | |
mCategoryRecyclerView.addItemDecoration( | |
new DividerItemDecoration(getActivity(), null)); | |
``` | |
Custom divider with first also end and last dividers | |
```java | |
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."); | |
} | |
} | |
} |
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.
Great work, but how can I set the divider height?
Thank you
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.
Unfortunately, I get a double divider in between two rows of the RecyclerView
I comment out 50-52 lines, then "Show first divider" work.
How to show the last divider?
If i insert new item to top of the recycler view , there is no divider showing between first and second item.
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
I've forked it and added support for reverseLayout option in LinearLayoutManager:
https://gist.github.com/ceskobassman/179a62e1be65c2275baf
All reported problems in comments are fixed here:
https://gist.github.com/zokipirlo/82336d89249e05bba5aa
Use getChildAdapterPosition
instead getChildPosition
because getChildPosition
is deprecated.
How to set left or right margin for the divider? Is there any way out?
When I toggle between different items, the last divider always redraws itself. Is this a bug?
Hey! Thanks for everything! Looking very good!
I get a double divider in between two rows of the RecyclerView
it is good. thank you buddy
Great.. Thanks dude....
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! :)
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.
Thanks, works great!