Center Horizontal Last Row Using Recycler GridLayoutManager Range

I am trying to make the elements of the last horizontal row of lines in the form of recyclers. I use GridLayoutManager to achieve functionality. Using setSpanSizeLookup , I want to adjust the size of the range for the last row, as indicated by messages on SO, but unfortunately I can’t keep track of which row is currently being filled, so my logic does not work.

What I want to achieve:

enter image description here

the code:

 static private int NUM_OF_COLUMNS = 3; final GridLayoutManager manager = new GridLayoutManager(getBaseActivity(), NUM_OF_COLUMNS); manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { int rowNum = 0; @Override public int getSpanSize(int position) { int spanSize = 1; if(position == 0) rowNum = 0; //reset it //check if it is last row int numOfRows = (int) Math.ceil((double) list.size() / NUM_OF_COLUMNS); if(rowNum == numOfRows - 1) { //get num of items in last row int items = list.size() - (NUM_OF_COLUMNS * rowNum); if(items == 1) spanSize = 3; } if(rowNum % NUM_OF_COLUMNS == 0) //if last element rowNum++; return spanSize; } }); recyclerView.setLayoutManager(manager); 

The above code controls the row number, since I don’t know how to get the current row and column position for the grid. Can someone point in the right direction? Thanks.

+13
source share
2 answers

Look at that . This is a Google library that provides similar CSS Flexible Box Layout Module features for Android.

in activity

  FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(); layoutManager.setFlexWrap(FlexWrap.WRAP); layoutManager.setFlexDirection(FlexDirection.ROW); layoutManager.setAlignItems(AlignItems.CENTER); viewDecks.setLayoutManager(layoutManager); 

in Adapter.ViewHolder

 ViewGroup.LayoutParams lp = itemView.getLayoutParams(); if (lp instanceof FlexboxLayoutManager.LayoutParams) { FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp; flexboxLp.setFlexGrow(1.0f); flexboxLp.setAlignSelf(AlignSelf.CENTER); } 

and make sure you set android:layout_gravity="center"

+4
source

I suppose, with a known number of elements in the adapter, you can write with a simple extension for the GridLayoutManager class.

I just needed this, so here is a working solution ...

 /** * Get grid layout manager with special optimization for span of the last row. * In case, last row won't have same number of items as previous rows, its content * will be spread over whole row. * * @param ctx current context * @param spanCount number of items per row * @param itemsCount number of items in adapter * @param orientation manager orientation * @param reverseLayout flag for orientation direction */ fun getGridManagerLastRowCenter(ctx: Context, spanCount: Int, itemsCount: Int, @RecyclerView.Orientation orientation :Int, reverseLayout: Boolean) : GridLayoutManager { // get number of items in last row val lastRowCount = itemsCount % spanCount if (lastRowCount == 0) { return GridLayoutManager(ctx, spanCount, orientation, reverseLayout) } // number of rows with all items val fullRows = itemsCount / spanCount // "span" counter for whole row (as minimum divider) val rowSpan = spanCount * lastRowCount // span value for item in the first rows val baseRowItemSpan = rowSpan / spanCount // span value for item in the last row val lastRowItemSpan = rowSpan / lastRowCount // return generated manager return GridLayoutManager(ctx, rowSpan, orientation, reverseLayout).apply { spanSizeLookup = object: GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { return if (position / spanCount < fullRows) { baseRowItemSpan } else { lastRowItemSpan } } } } } 

Use with a simple call

rv.layoutManager = UtilsListAco.getGridManagerLastRowCenter( ctx, 3, items.size, RecyclerView.VERTICAL, false)

0
source

Source: https://habr.com/ru/post/1013331/


All Articles