How do I calculate the required height of a GridView that is inside of a ScrollView on Android?

烈酒焚心 提交于 2019-12-14 03:47:14

问题


I have a GridView inside of a LinearLayout inside of a ScrollView that pages in data from the server. Beneath the GridView is a button to load more data. My GridView will have an ultimate height that is larger than the screen. If I set the height of my GridView to either wrap_content or parent_fill, it sizes itself to the exact available on-screen height and does not scroll at all, cropping out the extra rows. If I explicitly set the layout_height to something large, like 1000dip, scrolling behaves properly, however I cannot predict the final height of my scroll view apriori.

How do I programmatically determine the necessary height of a GridView to get the desired behaviour?

Here is my layout below. As you can see I set the height to 1000dip, but that is bogus, I need that value to get set automatically/programmatically:

        <ScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true"        
    android:layout_weight="1"       
    >   
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"    
            >

            <GridView xmlns:android="http://schemas.android.com/apk/res/android" 
                android:id="@+id/grid"
                android:layout_width="fill_parent" 
                android:layout_height="1000dip"
                android:columnWidth="70dp"
                android:numColumns="auto_fit"
                android:verticalSpacing="0dp"
                android:horizontalSpacing="0dp"
                android:stretchMode="columnWidth"
                android:gravity="center"
                android:background="#000000"
                android:layout_weight="1"
            />
            <Button
            android:id="@+id/load_more"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content"
            android:text="Load More Foo" 
            />
        </LinearLayout>
    </ScrollView>

回答1:


Here is one way to do this, if someone needs it. A bit of a hack but does the trick. You have to set GridView initially big enough for all the views (e.g. 10000dip)

final GridView imageContainer = // your GridView
imageContainer.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() 
            {
            @Override
            public void onGlobalLayout() 
                {
                imageContainer.getViewTreeObserver().removeGlobalOnLayoutListener( this );
                View lastChild = imageContainer.getChildAt( imageContainer.getChildCount() - 1 );
                imageContainer.setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, lastChild.getBottom() ) );
                }
            });



回答2:


I know it's an old case, but I had a similar problem where my ScrollView contained multiple LinearLayouts, which in their turn contained a header and a GridView. Basically I made categorised sections with headers containing images belonging to that category. The GridView had to have a flexible height.

I found a lot of answers about overriding onMeasure(), but it worked only on some devices, not all. The height would eventually be 1, or 3 or just 0, displaying only a few pixels of the image.

StretchingGridView class

I overrode the drawableStateChanged() method with this code, inspired by @Karitsa's solution:

@Override
public void drawableStateChanged() {
    getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            getViewTreeObserver().removeOnGlobalLayoutListener( this );
            View lastChild = getChildAt( getChildCount() - 1 );
            if (lastChild != null) {
                int height = Math.max(lastChild.getBottom(), getColumnWidth());
                float child = getAdapter().getCount();
                float col = getNumColumns();
                int rows = (int) Math.ceil(child / col);
                height = rows * getColumnWidth() + (getHorizontalSpacing() * rows-1);
                setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, height ) );
            }
        }
    });
}

Note: My GridView uses square images, so I base the height on their width. I don't think it works well with flexible grid item heights.




回答3:


Apparently GridViews inside ScrollViews are not kosher in Android-land. Switching to ListView with custom-made rows. That seems to behave better.



来源:https://stackoverflow.com/questions/3682445/how-do-i-calculate-the-required-height-of-a-gridview-that-is-inside-of-a-scrollv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!