3

So i am using RecyclerView with GridLayoutManager the spacing between the items is not consistent around the item

This is how it looks in 4 x 4 Grid

This is how it looks in 5 x 5 grid

I already tried many solution from this and this and this

But nothing worked for me

Here is my how i am setting my adapter

mLayoutManager = new GridLayoutManager(mContext, 5);
        mRecyclerView.setLayoutManager(mLayoutManager);

        int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.spacing);
        mRecyclerView.addItemDecoration(new SpacesItemDecoration(spacingInPixels));

And this is my SpacesItemDecoration class

public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private int space;

    public SpacesItemDecoration(int space) {
        this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view,RecyclerView parent, RecyclerView.State state)
    {
        outRect.left = space;
        outRect.right = space;
        outRect.top = space;
        outRect.bottom = space;

        // Add top margin only for the first item to avoid double space between items
        if (parent.getChildLayoutPosition(view) == 0)
        {
            outRect.top = space;
        }
        else
        {
            outRect.top = 0;
        }
    }
}

I don't know why it is not working for me

There is no margin or padding to my recyclerview & item

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
Akshay Katariya
  • 338
  • 4
  • 16
  • looks like the below code is causing problems , check it remove and check `int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.spacing); mRecyclerView.addItemDecoration(new SpacesItemDecoration(spacingInPixels));` – Vinay Sasalatti Apr 13 '18 at 08:31
  • It is used to add spacing around my item view there is nothing wrong here i think & `R.dimen.spacing = 10dp` – Akshay Katariya Apr 13 '18 at 08:34
  • looks like this code is causing this issue `items if (parent.getChildLayoutPosition(view) == 0) { outRect.top = space; } else { outRect.top = 0; }` – Vinay Sasalatti Apr 13 '18 at 08:39
  • outRect.top = space; don't use it before the if condition. You are initializing it in if condition. Try this link https://stackoverflow.com/questions/28531996/android-recyclerview-gridlayoutmanager-column-spacing?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – AmitCharkha Apr 13 '18 at 09:08
  • @AmitCharkha have you read my full question i have already referred this links – Akshay Katariya Apr 13 '18 at 09:43

3 Answers3

0

when you bind adapter into recycler view. in adapter make layout that provide layout in view control size. like adapter_row.xml

    <ImageView
    android:layout_width="@dimen/_100sdp"
    android:layout_height="@dimen/_100sdp" 
    android:id="@+id/amIvImage"
    android:src="@drawable/a"/>

and if you want space is same in all the device used below dependency . add in app level gradle file..

 implementation 'com.intuit.sdp:sdp-android:1.0.4'
0

You don't really say what is the correct layout. I assume that you want a space on top of all items in the first row. Currently, there is only a top space on the first item. Your issue is with the following code:

// Add top margin only for the first item to avoid double space between items
if (parent.getChildLayoutPosition(view) == 0)
{
    outRect.top = space;
}
else
{
    outRect.top = 0;
}

This code will give a top space only to the first item in the RecyclerView since parent.getChildLayoutPosition(view) gives you the adapter position. You will want to check to see if the view is in the first row of the RecyclerView and adjust accordingly.


Looking at this again, I see that the spacing between vertical cells is greater than between horizontal cells. This is happening because you are applying spacing to the top and bottom of the cells. If you want the same spacing around all cells you will need to do the following:

  • Apply spacing to the top and left side of all cells. Do not automatically apply right or bottom spacing. This will fix most of your problem, but will not apply spacing to the rightmost column or to the bottom row.

  • Detect when a cell is in the rightmost column and apply spacing to the right-hand side. For a 4x4 grid the positions of these cells will be every fourth adapter positions. So, the adapter positions to get right spacing are 3, 7, 11, etc. or (position + 1) % 4 == 0.

  • Detect when a cell is in the bottom row and apply spacing to the bottom. For a 4x4 grid, the items in the last row will be 4 or less from the last position in the RecyclerView or (maxPosition - position) < 4.

Depending upon what exactly you want to do, you may have to check for some edge cases such as when the RecyclerView doesn't have enough items to fill the last row.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
0

i figured this out and will give you some clues. gridlayoutmanager is scaling the items such that it will fit htem all according to your span count. so imageine that gridlayoutmanager takes your item and says how can i stretch this item such that X number of them can fit on a row ?

the best approach i found is to use constraintLayout. such as:

 app:layout_constraintDimensionRatio="1:2" 

and/or depending your usecase for your content you can use this so it stretches with the container:

eg.

app:layout_constraintWidth_percent=".51"
app:layout_constraintHeight_percent=".63"

and not give any hard dimensions. Hard dimensions are going to make the spacing not even as its forcing a certain size when gridlayoutmanager wants to strength to fit your item. instead let the system scale the items but maintain the aspect ratio.

all these examples are for your container. inside your container you can create content as you usually do but you might still need ayout_constraintWidth_percent so it stretches when the item stretches proportionally.

j2emanue
  • 60,549
  • 65
  • 286
  • 456