Get GridView actual column width in Android
Asked Answered
F

3

5

Hello fellow developers.

I have a Grid View in an android application. The grid view has the setting to automatically fit the number of columns and has a minimum column width of 250 pixels.

Inside the grid cells, I have a LinearLayout that has an Image View and some Text Views.

I want my Image View to be always square, but unfortunately I was not able to do this with any layout settings (open to suggestions here, if there is an option I missed).

So my idea is that I should somehow get the grid column width in my image Loading class and adjust the imageView height dynamically there, to match the width.

I failed getting the column width though. If I set a breakPoint in my public View getView(int position, View convertView, ViewGroup parent) I see that my parent ViewGroup is the Grid and it has the correct value of the column width, but when I use:

GridView mGridView = (GridView)parent;
int width = mGridView.getColumnWidth();

the app crashes as it says there is no getColumnWidth method.

Any help here?

Festschrift answered 6/1, 2013 at 22:8 Comment(1)
getColumnWidth added from API 16, you may be running in older version of android.Canonry
C
6

The solution may be extending your ImageView and overriding onMesure() method according to your requirement:

onMeasure(int widthMeasureSpec, int heightMeasureSpec){
   super.onMeasure(widthMeasureSpec,heightMeasureSpec);
   setMeasuredDimension(getMeasuredWidth(),getMeasuredWidth());

}
Canonry answered 7/1, 2013 at 0:10 Comment(1)
Thank you, I will try it out and let you know!Festschrift
G
6

Just in case someone is looking for a way to get the actual columnWidth pre api 16(as was i when i saw this post), this is how i retrieve it.

I extended the GridView and overrode the getColumnWidth Method with this one

@SuppressLint("NewApi")
@Override
public int getColumnWidth() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        return super.getColumnWidth();
    else {
        try {
            Field field = GridView.class.getDeclaredField("mColumnWidth");
            field.setAccessible(true);
            Integer value = (Integer) field.get(this);
            field.setAccessible(false);

            return value.intValue();
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
Gummy answered 6/11, 2013 at 15:35 Comment(0)
P
1

An alternative to Daniel Bo's answer is to manually calculate the value:

private int getColumnWidth(Context context, GridView gridView) {
    if (android.os.Build.VERSION.SDK_INT >= 16)
        return gridView.getColumnWidth();

    Resources res = context.getResources();
    int lPad = (int)res.getDimension(R.dimen.left_padding);
    int rPad = (int)res.getDimension(R.dimen.right_padding);
    int hSpace = (int)res.getDimension(R.dimen.horizontal_spacing);
    int cols = gridView.getNumColumns();
    int width = gridView.getWidth();

    return (width - lPad - rPad + hSpace) / cols - hSpace;
}

Notice that this only works for API higher than 11 (Honeycomb) and assumes you set up the GridView with some values defined as resources. Consider for example that you have a dimens.xml that has:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="left_padding">4dp</dimen>
    <dimen name="right_padding">8dp</dimen>
    <dimen name="horizontal_spacing">2dp</dimen>
</resources>

And then your layout XML file has:

<GridView
    ...
    android:horizontalSpacing="@dimen/horizontal_spacing"
    android:paddingLeft="@dimen/left_padding"
    android:paddingRight="@dimen/right_padding"
    ...
    />

And if you have many similar GridViews, it might be a good idea to put these properties in a custom style.

At least this worked for me without having to use reflection. Note that it would probably be overkill to call this function frequently.

Hope this helps someone.

Polariscope answered 12/1, 2014 at 16:6 Comment(2)
since getNumColumns is an api 11 call, you cant use if you want to port back further.Gummy
Thanks for the catch =) I'll place a warning on the answer.Polariscope

© 2022 - 2024 — McMap. All rights reserved.