Hi I am Following this tutorial:
http://www.journaldev.com/10024/android-recyclerview-and-cardview-example-tutorial
Now I am facing a weird issue the margin between each CardView
item inside RecyclerView
is way too much.
ISSUE
How to reduce the Margin between each item of CardView
placed inside RecyclerView
?
This question is related to
android
android-recyclerview
android-cardview
Instead of using XML to add margin between items in RecyclerView, it's better way to use RecyclerView.ItemDecoration that provide by android framework.
So, I create a library to solve this issue.
https://github.com/TheKhaeng/recycler-view-margin-decoration
Try to add RecyclerView.ItemDecoration
To know how to do that: How to add dividers and spaces between items in RecyclerView?
If you want to do it in XML, jus set paddingTop
and paddingLeft
to your RecyclerView
and equal amount of layoutMarginBottom
and layoutMarginRight
to the item you inflate into your RecyclerView
(or vice versa).
I made a class to manage this issue. This class set different margins for the items inside the recyclerView: only the first row will have a top margin and only the first column will have left margin.
public class RecyclerViewMargin extends RecyclerView.ItemDecoration {
private final int columns;
private int margin;
/**
* constructor
* @param margin desirable margin size in px between the views in the recyclerView
* @param columns number of columns of the RecyclerView
*/
public RecyclerViewMargin(@IntRange(from=0)int margin ,@IntRange(from=0) int columns ) {
this.margin = margin;
this.columns=columns;
}
/**
* Set different margins for the items inside the recyclerView: no top margin for the first row
* and no left margin for the first column.
*/
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildLayoutPosition(view);
//set right margin to all
outRect.right = margin;
//set bottom margin to all
outRect.bottom = margin;
//we only add top margin to the first row
if (position <columns) {
outRect.top = margin;
}
//add left margin only to the first column
if(position%columns==0){
outRect.left = margin;
}
}
}
you can set it in your recyclerview this way
RecyclerViewMargin decoration = new RecyclerViewMargin(itemMargin, numColumns);
recyclerView.addItemDecoration(decoration);
Use CardView
in Recyclerview
Item Layout like this :
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools"
card_view:cardCornerRadius="10dp"
app:cardBackgroundColor="#ACACAC"
card_view:cardElevation="5dp"
app:contentPadding="10dp"
card_view:cardUseCompatPadding="true">
Use CompatPadding in CardView Item
Find the attribute card_view:cardUseCompatPadding="true"
in cards_layout.xml and delete it. Start app and you will find there is no margin between each cardview item.
Add margin attributes you like. Ex:
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
In XML, to manage margins between items of a RecyclerView, I am doing in this way, operating on these attributes of detail layout (I am using a RelativeLayout):
of course it is also very important to set these attributes:
Here follows a complete example, this is the layout for the list of items:
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:name="blah.ui.meetings.MeetingEventFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginVertical="2dp"
app:layoutManager="LinearLayoutManager"
tools:context=".ui.meetings.MeetingEventFragment"
tools:listitem="@layout/fragment_meeting_event" />
and this is the detail layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
android:background="@drawable/background_border_meetings">
<TextView
android:id="@+id/slot_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="slot_type"
/>
</RelativeLayout>
background_border_meetings is just a box:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- This is the stroke you want to define -->
<stroke android:width="4dp"
android:color="@color/mdtp_line_dark"/>
<!-- Optional, round your corners -->
<corners android:bottomLeftRadius="2dp"
android:topLeftRadius="2dp"
android:bottomRightRadius="2dp"
android:topRightRadius="2dp" />
<gradient android:startColor="@android:color/transparent"
android:endColor="@android:color/transparent"
android:angle="90"/>
</shape>
change in Recycler view match_parent to wrap_content:
<android.support.v7.widget.RecyclerView
android:id="@+id/recycleView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Also change in item layout xml
Make parent layout height match_parent to wrap_content
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
Source: Stackoverflow.com