Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Recyclerview GridLayoutManager column spacing

How do you set the column spacing with a RecyclerView using a GridLayoutManager? Setting the margin/padding inside my layout has no effect.

like image 590
Nick H Avatar asked Feb 15 '15 22:02

Nick H


People also ask

How do I set GridLayoutManager spacing?

In your source code, add ItemOffsetDecoration to your RecyclerView. Item offset value should be half size of the actual value you want to add as space between items. mRecyclerView. setLayoutManager(new GridLayoutManager(context, NUM_COLUMNS); ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(context, R.

How to give space between RecyclerView items in Android?

The simplest way is to add top/bottom margins around the first item in the adapter's row. android:layout_marginBottom="4dp".

How do I remove spaces between items in RecyclerView?

Try to use cardElevation=0dp. This should remove the extra spacing between recyclerview items.


2 Answers

Following code works well, and each column has same width:

public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {      private int spanCount;     private int spacing;     private boolean includeEdge;      public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {         this.spanCount = spanCount;         this.spacing = spacing;         this.includeEdge = includeEdge;     }      @Override     public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {         int position = parent.getChildAdapterPosition(view); // item 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;             }             outRect.bottom = spacing; // 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; // item top             }         }     } } 

Usage

1. no edge

enter image description here

int spanCount = 3; // 3 columns int spacing = 50; // 50px boolean includeEdge = false; recyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, includeEdge)); 

2. with edge

enter image description here

int spanCount = 3; // 3 columns int spacing = 50; // 50px boolean includeEdge = true; recyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, includeEdge)); 
like image 50
xuxu Avatar answered Sep 20 '22 21:09

xuxu


RecyclerViews support the concept of ItemDecoration: special offsets and drawing around each element. As seen in this answer, you can use

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

Then add it via

mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view); int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.spacing); mRecyclerView.addItemDecoration(new SpacesItemDecoration(spacingInPixels)); 
like image 35
ianhanniballake Avatar answered Sep 19 '22 21:09

ianhanniballake