Set Fixed GridView Row Height
Asked Answered
R

3

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;
    }
Russia answered 29/5, 2013 at 16:19 Comment(4)
if possible please post the screenshot of stretched rowsNewmann
@MehulJoisar please refer to pictures for details.Russia
android:stretchMode="spacingWidthUniform" is not what you wanted?Wonderstricken
This also works with my answer, but only if I manually set android:columnWidth="320dp", I was hoping not to set it by hand.Russia
R
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>
Russia answered 5/6, 2013 at 21:10 Comment(0)
T
50

In the CustomAdapter

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

rowHigh is the dimension you must change

Transnational answered 20/3, 2014 at 19:4 Comment(2)
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.Inherited
Specifically, it should go in getView() or newView() I believe. See example in documentation: developer.android.com/guide/topics/ui/layout/…Genova
R
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>
Russia answered 5/6, 2013 at 21:10 Comment(0)
L
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"/>
Laundress answered 7/8, 2014 at 9:2 Comment(1)
Taken from jayway.com/2012/10/04/…Neodarwinism

© 2022 - 2024 — McMap. All rights reserved.