Linkang Ma
Linkang Ma

Reputation: 177

Why is the space between my RecyclerView items not the same?

I use ItemDecoration to set the space between the grid RecyclerView items, and I want the space between each item to be equal.

enter image description here ItemDecoration

public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpaceItemDecoration(int space) {
    this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    if (parent.getLayoutManager() instanceof GridLayoutManager) {
        GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams();
        GridLayoutManager gridLayoutManager = (GridLayoutManager) parent.getLayoutManager();
        int spanSize = layoutParams.getSpanSize();
        int spanIndex = layoutParams.getSpanIndex();
        int totalSpanSize = gridLayoutManager.getSpanCount();
        if (spanIndex == 0) {//left
            outRect.left = space;
            outRect.right = space / 2;
        } else if (spanSize + spanIndex == totalSpanSize) {//right
            outRect.right = space;
            outRect.left = space / 2;
        } else if (spanIndex > 0 && spanSize + spanIndex < totalSpanSize) {
            outRect.left = space / 2;
            outRect.right = space / 2;
        }
        outRect.bottom = space;
    }
}

RecyclerView

    <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"/>

item xml

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="90dp"
android:layout_height="90dp"
android:background="#ff6600"
android:orientation="vertical">

</LinearLayout>

Upvotes: 2

Views: 7465

Answers (4)

Komal12
Komal12

Reputation: 3348

Try this,

int spanCount;
final private Context mContext =YourActivity.this;
int value = activity.getResources().getConfiguration().orientation;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_login);
    recycler_view=(RecyclerView)findViewById(R.id.recycler_view);

    recycler_view.setLayoutManager(new GridLayoutManager(mContext, 2));
    if (value == Configuration.ORIENTATION_PORTRAIT) {
        spanCount = 2;
    }
    else if (value == Configuration.ORIENTATION_LANDSCAPE) {
        spanCount = 3;
    }
    int spacing_left = 50; // 50px
    int spacing_top=10;
    
    recycler_view.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing_left, spacing_top));
}

@Override
protected void onResume() {

    if (value == Configuration.ORIENTATION_PORTRAIT) {
        spanCount = 2;
    }
    else if (value == Configuration.ORIENTATION_LANDSCAPE) {
        spanCount = 3;
    }

    super.onResume();
}

GridSpacingItemDecoration:

/* set spacing for grid view */
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration
{
    final private int spanCount,spacing,spacing_top;
    final private boolean includeEdge;

    public GridSpacingItemDecoration(int spanCount, int spacing_left, int spacing_top)
    {
        this.spanCount = spanCount;
        this.spacing = spacing_left;
        this.includeEdge = true;
        this.spacing_top=spacing_top;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
    {
        int position = parent.getChildAdapterPosition(view); // item phases_position
        int column = position % spanCount; // item column

        if (includeEdge)
        {
            outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
            outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

            if (position < spanCount)
            { // top edge
                outRect.top = spacing_top;
            }
            outRect.bottom = spacing_top; // item bottom
        }
        else
        {
            outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
            outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)
            if (position >= spanCount)
            {
                outRect.top = spacing_top; // item top
            }
        }
    }
}

Upvotes: 2

Ferdous Ahamed
Ferdous Ahamed

Reputation: 21736

Use GridItemDecoration:

import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.DimenRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class GridItemDecoration extends RecyclerView.ItemDecoration {

    private int mItemOffset;

    public GridItemDecoration(int itemOffset) {
        mItemOffset = itemOffset;
    }

    public GridItemDecoration(@NonNull Context context, @DimenRes int itemOffsetId) {
        this(context.getResources().getDimensionPixelSize(itemOffsetId));
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                               RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.set(mItemOffset, mItemOffset, mItemOffset, mItemOffset);
    }
}

From your Activity:

RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ................
    ........................

    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);

    mRecyclerView.setHasFixedSize(true);

    // Grid layout manager
    mLayoutManager = new GridLayoutManager(mContext, 3); // spanCount = 3 for 3 columns
    mRecyclerView.setLayoutManager(mLayoutManager);

    // Grid item spacing
    GridItemDecoration itemDecoration = new GridItemDecoration(mContext, R.dimen.grid_item_spacing); // R.dimen.grid_item_spacing is 2dp
    mRecyclerView.addItemDecoration(itemDecoration);

    ............
    ......................
}

Upvotes: 2

Fathima km
Fathima km

Reputation: 2699

Add android:scaleType="fitXY" inside your item xml which will scale the image using FILL so that all items occupy same area.

Upvotes: -1

Giorgos Pippos
Giorgos Pippos

Reputation: 63

Why don't you try to remove the code for the custom spacing, and use the grid parameters android:horizontalSpacing and android:verticalSpacing?

Upvotes: 0

Related Questions