How to have a GridView that adapts its height when items are added
Use this code
public class MyGridView extends GridView {
public MyGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyGridView(Context context) {
super(context);
}
public MyGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
I have done this way:
This code will set GridView
height as per number of Child.
Note: Where 5
is number of columns.
private void setDynamicHeight(GridView gridView) {
ListAdapter gridViewAdapter = gridView.getAdapter();
if (gridViewAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
int items = gridViewAdapter.getCount();
int rows = 0;
View listItem = gridViewAdapter.getView(0, null, gridView);
listItem.measure(0, 0);
totalHeight = listItem.getMeasuredHeight();
float x = 1;
if( items > 5 ){
x = items/5;
rows = (int) (x + 1);
totalHeight *= rows;
}
ViewGroup.LayoutParams params = gridView.getLayoutParams();
params.height = totalHeight;
gridView.setLayoutParams(params);
}
Hope this will help you.
Developed on the idea shared by https://stackoverflow.com/users/4233197/hiren-patel, so Thank You :)
Pass you GridView and its number of columns through this function and you are done.
private void setGridViewHeightBasedOnChildren(GridView gridView, int noOfColumns) {
ListAdapter gridViewAdapter = gridView.getAdapter();
if (gridViewAdapter == null) {
// adapter is not set yet
return;
}
int totalHeight; //total height to set on grid view
int items = gridViewAdapter.getCount(); //no. of items in the grid
int rows; //no. of rows in grid
View listItem = gridViewAdapter.getView(0, null, gridView);
listItem.measure(0, 0);
totalHeight = listItem.getMeasuredHeight();
float x;
if( items > noOfColumns ){
x = items/noOfColumns;
//Check if exact no. of rows of rows are available, if not adding 1 extra row
if(items%noOfColumns != 0) {
rows = (int) (x + 1);
}else {
rows = (int) (x);
}
totalHeight *= rows;
//Adding any vertical space set on grid view
totalHeight += gridView.getVerticalSpacing() * rows;
}
//Setting height on grid view
ViewGroup.LayoutParams params = gridView.getLayoutParams();
params.height = totalHeight;
gridView.setLayoutParams(params);
}
When onMeasure() is called for GridView, if heightMode is MeasureSpec.UNSPECIFIED, then the gridview will be as tall as all of it's contained elements (plus some padding).
To ensure that this is the case, you can make a quick custom view extending GridView and including the following override:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
}
This is working for me:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background" >
<!-- MORE LAYOUTS IF YOU WANT -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:fillViewport="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- MORE LAYOUTS IF YOU WANT -->
<GridView
android:id="@+id/gridview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" >
</GridView>
<!-- MORE LAYOUTS IF YOU WANT -->
</RelativeLayout>
</ScrollView>
</RelativeLayout>