How to center content of GridLayoutManager?

Viewed 949

Just trying to center my RecyclerView horizontal.

Here is the xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">



    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent" 
        android:layout_height="match_parent"/>


</RelativeLayout>

And here the java code:

mRecyclerView = findViewById(R.id.recycler_view);
itemLayoutManager = new GridLayoutManager(this, 6);
mRecyclerView.setLayoutManager(itemLayoutManager);
...
mItemAdapter = new ItemAdapter(MainActivity.this, mItemList);
mRecyclerView.setAdapter(mItemAdapter);

When I run the application the recyclerview aligns left. What exactly do I have to do to center the content so that the margin is the same left and right like in the example picture on the right side?

enter image description here

2 Answers

Create a class like to set paddings to item:

class SpacingItemDecorator (private val padding: Int) : RecyclerView.ItemDecoration()
{
    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    )
    {
        super.getItemOffsets(outRect, view, parent, state)
        outRect.top = padding
        outRect.bottom = padding
        outRect.left = padding
        outRect.right = padding
    }
}

Now in Your RecyclerView set paddingStart and paddingEnd, e.g 4dp :

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingStart="4dp"
    android:paddingEnd="4dp"
    app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
    app:spanCount="6"/>

When You create adapter just apply this item decorator:

val x = (resources.displayMetrics.density * 4).toInt() //converting dp to pixels
recyclerView.addItemDecoration(SpacingItemDecorator(x)) //setting space between items in RecyclerView

RecyclerView item:

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="6dp"
    app:cardElevation="4dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/txtContent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{Integer.toString(dataView.id)}"
            android:textSize="20sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

Result:

enter image description here

I faced the same issue recently and looked into the source code. There's no straight forward way to do this using GridLayoutManager. The other was is to use a GridView which is more customisable.

This is an alternate solution for you or any one else looking for a workaround.

I didn't want to change to a GridView so this is what I did. I set the RecyclerView's layout width to wrap_content and centered it horizontally within the parent (which in your case is a RelativeLayout so it will be something like android:centerHorizontally="true")

I knew the item width so I calculated the spanCount by dividing the screen width by the item width (plus any horizontal margins). Now I set the span count to the grid layout manager and it gets centered horizontally just how you want it.

Adding margins to you item's layout root play an important role here.

Related