[android] Margin between items in recycler view Android

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?

enter image description here

This question is related to android android-recyclerview android-cardview

The answer is


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

enter image description here



If you want to do it in XML, jus set paddingTopand 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


  1. 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.

  2. 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):

  • android:layout_marginTop
  • android:layout_marginBottom

of course it is also very important to set these attributes:

  • android:layout_width="wrap_content"
  • android:layout_height="wrap_content"

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"
    />

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to android-recyclerview

Failed to resolve: com.android.support:cardview-v7:26.0.0 android CardView background color always white Changing background color of selected item in recyclerview Simple Android grid example using RecyclerView with GridLayoutManager (like the old GridView) Simple Android RecyclerView example Android Horizontal RecyclerView scroll Direction Margin between items in recycler view Android How to add a recyclerView inside another recyclerView RecyclerView - Get view at particular position Recyclerview inside ScrollView not scrolling smoothly

Examples related to android-cardview

CardView background color always white Margin between items in recycler view Android How to add colored border on cardview? How to add a recyclerView inside another recyclerView CardView Corner Radius CardView not showing Shadow in Android L RecyclerView inside ScrollView is not working Ripple effect on Android Lollipop CardView How do I get the position selected in a RecyclerView? Change the background color of CardView programmatically