13

I am having all sorts of issues with row heights in GridView.

I would like to set the size of the items (height/width) in XML and then just have the GridView autofit as many of them as it can with no stretching. If it can't fit the next element it should just add padding around the current number of elements it was able to fit.

Currently I get 2 columns (which to me almost seems fixed size) and the rows get stretched. Could someone please help explain what is happening and how to achieve what I want?

GridView:

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/main_grid"
    android:numColumns="auto_fit"
    android:gravity="center"
    android:paddingRight="20dp"
    android:paddingLeft="20dp"
    android:clipToPadding="true"
    android:fitsSystemWindows="true"
    android:stretchMode="none"
    android:background="@drawable/main_grid_background">

</GridView>

GridItem (I want it 320x320 as I later insert a background image into it which looks odd if its not a perfect square).

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="320dp"
    android:layout_height="320dp"
    android:padding="10dp" >

    <TextView
        android:id="@+id/grid_item_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:text="@+id/label"
        android:layout_marginTop="5dp"
        android:textColor="@color/black"
        android:textSize="15sp"
        android:visibility="invisible"
        android:layout_centerInParent="true" >
    </TextView>

</RelativeLayout>

Java:

public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View gridView;

        if (convertView == null) {

            gridView = new View(context);

            // get layout from mobile.xml
            gridView = inflater.inflate(R.layout.main_grid_item, null);

        } else {
            gridView = (View) convertView;
        }
        TextView textView = (TextView) gridView
                .findViewById(R.id.grid_item_label);

            //SET TEXT AND BACKGROUND IMAGE HERE
            //gridView.setBackgroundResource(R.drawable.main_grid_item_import);



        return gridView;
    }
AlexIIP
  • 2,461
  • 5
  • 29
  • 44

3 Answers3

50

In the CustomAdapter

v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, rowHigh));

rowHigh is the dimension you must change

Boris Karloff
  • 1,190
  • 12
  • 20
  • 1
    Thanks for this. Depending on the app, you might want to call this within v.post(new Runnable...) upon making v as final or equivalent ViewHolder object being final. I have a 'close' button in a cell which removes itself (list.remove(position)) and calls notifyDataSetChanged(). Just plain setLayoutParams acted on me (rendering timing was messed up) and putting it in post fixed it. – st_bk May 01 '15 at 18:35
  • 1
    Specifically, it should go in getView() or newView() I believe. See example in documentation: http://developer.android.com/guide/topics/ui/layout/gridview.html#example – John Cummings Nov 19 '15 at 16:24
4

So, this is not a perfect answer but this is how I got it to work. Ideas borrowed from this thread.

All of this works assuming I know my image sizes, which are 320x320. Also, in GridView I had to set android:columnWidth="320dp" or it would not work. If someone has a better idea please post it... for now I am moving on.

Grid Item XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp" >
    <ImageView
    android:id="@+id/grid_item_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"/>
    <TextView
        android:id="@+id/grid_item_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:text="@+id/label"
        android:textColor="@color/black"
        android:layout_alignLeft="@+id/grid_item_image"
        android:layout_alignTop="@+id/grid_item_image"
        android:layout_alignRight="@+id/grid_item_image"
        android:layout_alignBottom="@+id/grid_item_image"
        android:gravity="center"
        android:textSize="15sp"
        android:visibility="invisible">
    </TextView>

</RelativeLayout>

GridView XML:

<GridView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/main_grid"
    android:numColumns="auto_fit"
    android:gravity="center"
    android:columnWidth="320dp"
    android:paddingRight="20dp"
    android:paddingLeft="20dp"
    android:clipToPadding="true"
    android:fitsSystemWindows="true"
    android:stretchMode="columnWidth"
    android:background="@drawable/main_grid_background">
</GridView>
Community
  • 1
  • 1
AlexIIP
  • 2,461
  • 5
  • 29
  • 44
4
public class MyGridView extends GridView {
    public MyGridView(Context context) {
        super(context);
    }

    public MyGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyGridView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightSpec;

        if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) {
            // The great Android "hackatlon", the love, the magic.
            // The two leftmost bits in the height measure spec have
            // a special meaning, hence we can't use them to describe height.
            heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
        } else {
            heightSpec = heightMeasureSpec;
        }

        super.onMeasure(widthMeasureSpec, heightSpec);
    }


}

In XML:

<MyGridView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/main_grid"
    android:gravity="center"/>
NightFury
  • 13,436
  • 6
  • 71
  • 120
Hitendra Joshi
  • 180
  • 1
  • 8