如何计算Android上ScrollView内部GridView所需的高度?

时间:2010-09-10 05:34:09

标签: android gridview android-linearlayout

我在ScrollView内部的LinearLayout内部有一个GridView,它可以从服务器中分页。 GridView下面是一个加载更多数据的按钮。我的GridView的最终高度将大于屏幕。如果我将GridView的高度设置为wrap_content或parent_fill,它会将自身调整为完全可用的屏幕高度,并且根本不滚动,裁剪出额外的行。如果我明确地将layout_height设置为大的,如1000dip,滚动行为正常,但是我无法预测滚动视图的最终高度apriori。

如何以编程方式确定GridView所需的高度以获得所需的行为?

以下是我的布局。正如您所看到的,我将高度设置为1000dip,但这是假的,我需要自动/以编程方式设置该值:

        <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>

3 个答案:

答案 0 :(得分:14)

如果有人需要,这是一种方法。有点黑客,但做的伎俩。您必须将GridView最初设置为足以支持所有视图(例如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() ) );
                }
            });

答案 1 :(得分:2)

我知道这是一个旧案例,但我遇到了类似的问题,我的ScrollView包含多个LinearLayout,其中包含一个标题和一个GridView。 基本上我使用包含属于该类别的图像的标题进行了分类。 GridView必须具有灵活的高度。

我找到了很多关于覆盖onMeasure()的答案,但它只适用于某些设备,而不是全部。高度最终将为1或3或仅为0,仅显示图像的几个像素。

StretchingGridView

我使用此代码覆盖drawableStateChanged()方法,受@ Karitsa解决方案的启发:

@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 ) );
            }
        }
    });
}

注意:我的GridView使用方形图像,因此我根据宽度确定高度。我认为灵活的网格物品高度并不适用。

答案 2 :(得分:1)

显然,ScrollViews中的GridViews在Android版本中并不是犹太人。使用自定义行切换到ListView。这似乎表现得更好。