Masksway
Masksway

Reputation: 225

How to set RecylerView item decoration in a GridLayout

I have simple grid layout with 2 spans, and my RecyclerView item layout looks like this:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/categoryCardView"
        android:layout_width="170dp"
        android:layout_height="100dp"
        app:cardBackgroundColor="@color/colorPrimary"
        app:cardCornerRadius="10dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

What I want is basically even space of all sides, so I set Item Decoration like this:

        recylcerView.addItemDecoration(SpacingItemDecorator(16))

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.right = padding
//        outRect.top = padding * 2

        outRect.top = padding
        outRect.right = padding/2
        outRect.left = padding/2
    }
}

But as I expected, I'm getting the wrong behavior. The top/bottom is okay, but if for example, I pass 16 padding to SpacingItemDecorator(as I said I've 2 items in a row), the first item will get 8 on the left as expected, but between the item, space will be 16 (8 from the right of the first item, 8 from the left of the second item).

But the weirdest thing is that the second items also get 16 from the right, instead of just 8(right padding)

My questions are:

  1. Why my second item in the row will get 16 padding from the right instead of just 8 as the first item get from the left?

  2. How can I set equal padding to all sizes?

Upvotes: 1

Views: 4203

Answers (2)

Branddd
Branddd

Reputation: 98

Just set your cardview width layout to Match parent, with a margin of 8dp for example. And a height with wrap_content. When dealing with recyclerViews. It's better avoid setting a specific measurement for width and height. Trust me, it will be way easier, and look better.

P.s. setting the dimension of a layout inside your activity/fragment has an effect on performance. Its also better to announce/define the UI inside you xml file.

Upvotes: 1

iknow
iknow

Reputation: 9872

To get 8dp padding for every RecyclerView item You can set RecyclerView padding to 4dp:

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

Now to Your ItemDecorator add this:

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
    }
}

And now in onCreate (or wherever You set RecylcerView) You can add this item decorator with padding set to 4:

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

Result:

enter image description here

Upvotes: 2

Related Questions