Skip to content

Instantly share code, notes, and snippets.

@janheinrichmerker
Last active March 11, 2024 08:26
Show Gist options
  • Save janheinrichmerker/2fcb22f160eefee6f07b to your computer and use it in GitHub Desktop.
Save janheinrichmerker/2fcb22f160eefee6f07b to your computer and use it in GitHub Desktop.
GridLayoutManager implementation that stretches to fit all grid items on screen and disables scrolling. Useful for dashboards etc.
package com.example;
import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.ViewGroup;
public class SpanningGridLayoutManager extends GridLayoutManager {
public SpanningGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public SpanningGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public SpanningGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return spanLayoutSize(super.generateDefaultLayoutParams());
}
@Override
public RecyclerView.LayoutParams generateLayoutParams(Context c, AttributeSet attrs) {
return spanLayoutSize(super.generateLayoutParams(c, attrs));
}
@Override
public RecyclerView.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
return spanLayoutSize(super.generateLayoutParams(lp));
}
@Override
public boolean checkLayoutParams(RecyclerView.LayoutParams lp) {
return super.checkLayoutParams(lp);
}
private RecyclerView.LayoutParams spanLayoutSize(RecyclerView.LayoutParams layoutParams){
if(getOrientation() == HORIZONTAL){
layoutParams.width = (int) Math.round(getHorizontalSpace() / Math.ceil(getItemCount() / getSpanCount()));
}
else if(getOrientation() == VERTICAL){
layoutParams.height = (int) Math.round(getVerticalSpace() / Math.ceil(getItemCount() / getSpanCount()));
}
return layoutParams;
}
@Override
public boolean canScrollVertically() {
return false;
}
@Override
public boolean canScrollHorizontally() {
return false;
}
private int getHorizontalSpace() {
return getWidth() - getPaddingRight() - getPaddingLeft();
}
private int getVerticalSpace() {
return getHeight() - getPaddingBottom() - getPaddingTop();
}
}
@alexcouret
Copy link

Hello, thanks this is exactly what I need, but unfortunately I don't know how to use it, the only thing that changes is that the scrolling is disabled. How do I call generateLayoutParams() ? Thank you !

@ishaan-khan
Copy link

Hi, thanks this is perfect but it does not handle orientation change. How do I handle that?

@janheinrichmerker
Copy link
Author

@OzoTek very late answer, but yeah, scrolling is disabled obviously because this layout manager just uses the whole screen space and distributes its items evenly in it. The goal was to have a "dashboard" style grid so that you don't need to scroll ;)

@janheinrichmerker
Copy link
Author

@ishaan-khan Not sure what you mean, but you should just reset the layout manager on orientation change.
Basicaly just call RecyclerView#setLayoutManager() again.

@brachu21
Copy link

I got problem with displaying a gridview, It's not displaying for example 7 element list in grid view, but only 6. How can I change it

@rhlmshr
Copy link

rhlmshr commented Nov 9, 2017

How to use it with the recyclerview ?

@a3349384
Copy link

Thanks very much!

@SubhashPrajapati
Copy link

not working below 5 Os devices

@himanshiThakur
Copy link

I want totally opposite of this i want to enable scrolling after adding n number of grid items . I want to enable horizontal and vertical scrolling simultaneously. Is this possible using recycler-view grid layout manager ?

@janheinrichmerker
Copy link
Author

@rhlmshr use RecyclerView.setLayoutManager(...)

@janheinrichmerker
Copy link
Author

@brachu21 @SubhashPrajapati If you're having issues, would you mind sharing a stack trace and/or screenshot?

@eypibee
Copy link

eypibee commented Jun 28, 2019

@brachu21 @SubhashPrajapati If you're having issues, would you mind sharing a stack trace and/or screenshot?

Hi @heinrichreimer,

I think I'm also experiencing the issue of @brachu21. This is my case:

ss

The first 3 columns containing 16 data each, displays exactly what I need but when it reached the last column with only 9 data, it only displays 8 and the last data was left as shown in the screenshot above.

@Ian-Butler-Novacoast
Copy link

spanLayoutSize should take into account any margins in the layoutParams

@vyguera
Copy link

vyguera commented Feb 20, 2020

First of all, thank you for this snippet. It has been of much help to me.

But I had a problem: as every item in the recyclerview has to appear on the screen, every time a change happens such as items are added or removed programmatically, all items has to be resized. Generally it works correctly but sometimes not, just only changing the item in question.
Also I had trouble when trying to change programatically the spanCount using setSpanCount.

Therefore, I made some changes to your code. I apologize I don't know how to make a new revision of this gist, and I have created a fork to upload my changes (maybe this is the right way to make a revision), what include:

  • Changed from java to kotlin
  • Override of checkLayoutParams method to invalidate all items sizes when a new item is added/removed.

You can find it at https://gist.github.com/vyguera/e6babe1995bff6e8694c2a14b69c595c

@yoonseopshin
Copy link

thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment