Reputation: 560
i am building an android app which is using RecyclerView
. I want to add dividers to RecyclerView
, which I did using this code:
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);
So far everything works fine. However, the divider is taking the size of full screen and I want to add margins to it. Is there any way that I can add margins to the divider using a method that will add some space to the rectangle drawn and not by creating a custom drawable shape with margins and add it to the RecyclerView
?
Upvotes: 42
Views: 33854
Reputation: 472
VERY SIMPLE SOLUTION
You should use MaterialDividerItemDecoration
This function remove last divider: isLastItemDecorated = false
These margin fuctions: dividerInsetStart/dividerInsetEnd
val decoration = MaterialDividerItemDecoration(
requireContext(),
DividerItemDecoration.VERTICAL
).apply {
isLastItemDecorated = false
}
decoration.dividerInsetStart = 40
decoration.dividerInsetEnd = 40
binding.recyclerView.addItemDecoration(decoration)
Upvotes: 0
Reputation: 397
Elaborating on @SeptimusX75: if you (like me) prefer to do UI stuff in XML you can create an inset drawable file. You'll have to create a second XML file but since in return your code gets cleaner I say it's worth it :-).
[UPDATE] as user @Zhou Hongbo suggest in the comments, using only one XML file: divider.xml:
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/divider_base"
android:insetRight="20dp"
android:insetLeft="20dp">
<shape>
<android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="@color/dividerColor" />
</shape>
</inset>
[OLD ANSWER]:
divider_base.xml (the actual divider):
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="@color/dividerColor" />
</shape>
divider.xml (the inset):
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/divider_base"
android:insetRight="20dp"
android:insetLeft="20dp">
</inset>
Upvotes: 7
Reputation: 1515
I found the best and simplest solution
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="40dp"
android:insetRight="40dp" >
<shape>
<size android:height="1dp"/>
<solid android:color="@color/recyclerview_divider" />
</shape>
</inset>
From: https://stackoverflow.com/a/40434249/5093308
Upvotes: 4
Reputation: 3460
Here is a simple Kotlin
code snippet to implement ItemDecoration
with RecyclerView
:
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
outRect.left = 20 // Left Margin.
outRect.right = 20 // Right Margin.
outRect.top = 16 // Top Margin.
outRect.bottom = 16 // Bottom Margin.
}
})
Explantation:- In the above example code, we are adding margins to each item of RecyclerView from all four directions.
Happy Coding...
Upvotes: 3
Reputation: 309
shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#E6E7F0" />
<size android:height="1dp" />
</shape>
layer.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/shape"
android:left="16dp"
android:right="16dp" />
</layer-list>
Code
val itemDecoration = DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
itemDecoration.setDrawable(resources.getDrawable(R.drawable.layer, null))
recyclerView.addItemDecoration(itemDecoration)
Upvotes: 21
Reputation: 88
Below is the code for divider in RecyclerView
with left margin. Just paste the code in your OnCreate
method of MainActivity
.
class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
public SimpleDividerItemDecoration(Context context) {
mDivider = context.getResources().getDrawable(R.drawable.divider);
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = 250;
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(
getApplicationContext()));
Since, the divider.xml
file will be missing from your drawable folder so below is the code that you have to paste on the divider layout after creating it on drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="1dp"
android:height="1dp" />
<solid android:color="@color/divider" />
</shape>
Upvotes: 0
Reputation: 1604
Use this and customize according to your requirement.
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable divider;
/**
* Default divider will be used
*/
public DividerItemDecoration(Context context) {
final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
divider = styledAttributes.getDrawable(0);
styledAttributes.recycle();
}
/**
* Custom divider will be used
*/
public DividerItemDecoration(Context context, int resId) {
divider = ContextCompat.getDrawable(context, resId);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + divider.getIntrinsicHeight();
divider.setBounds(left, top, right, bottom);
divider.draw(c);
}
}
}
Upvotes: 16
Reputation: 10906
Same like @Vivek answer but in Kotlin and different params
class SimpleItemDecorator : RecyclerView.ItemDecoration {
private var top_bottom: Int = 0
private var left_right: Int = 0
/**
* @param top_bottom for top and bottom margin
* @param left_right for left and right margin
*/
constructor(top_bottom: Int, left_right: Int = 0) {
this.top_bottom = top_bottom
this.left_right = left_right
}
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
super.getItemOffsets(outRect, view, parent, state)
outRect.bottom = top_bottom
outRect.top = top_bottom
outRect.right = left_right
outRect.left = left_right
}
}
Upvotes: 3
Reputation: 2195
I think the most straightforward solution is to use the setDrawable method on the Decoration object and pass it an inset drawable with the inset values you want for the margins. Like so:
int[] ATTRS = new int[]{android.R.attr.listDivider};
TypedArray a = context.obtainStyledAttributes(ATTRS);
Drawable divider = a.getDrawable(0);
int inset = getResources().getDimensionPixelSize(R.dimen.your_margin_value);
InsetDrawable insetDivider = new InsetDrawable(divider, inset, 0, inset, 0);
a.recycle();
DividerItemDecoration itemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
itemDecoration.setDrawable(insetDivider);
recyclerView.addItemDecoration(itemDecoration);
Upvotes: 76
Reputation: 5705
You can create your own item decoration for recycler view. Here is code for the same.
public class SimpleItemDecorator extends RecyclerView.ItemDecoration {
int space;
boolean isHorizontalLayout;
public SimpleItemDecorator(int space) {
this.space = space;
}
public SimpleItemDecorator(int space, boolean isHorizontalLayout) {
this.space = space;
this.isHorizontalLayout = isHorizontalLayout;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if(isHorizontalLayout)
{
outRect.bottom=space;
outRect.right=space;
outRect.left=space;
outRect.top=space;
} else {
outRect.bottom = space;
if (parent.getChildAdapterPosition(view) == 0)
outRect.top = space;
else
outRect.top = 0;
}
}
}
And to use it with your recyclerview you can do like this:
recyclerView.addItemDecoration(new SimpleItemDecorator(5));
Upvotes: 6