4

我在 ScrollView 内的 LinearLayout 内有一个 GridView,该 ScrollView 分页来自服务器的数据。GridView 下方是一个用于加载更多数据的按钮。我的 GridView 的最终高度将大于屏幕。如果我将 GridView 的高度设置为 wrap_content 或 parent_fill,它会将自身调整为屏幕上可用的确切高度,并且根本不会滚动,从而裁剪掉多余的行。如果我将 layout_height 显式设置为较大的值,例如 1000dip,则滚动行为正常,但是我无法先验地预测滚动视图的最终高度。

如何以编程方式确定 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>
4

3 回答 3

15

如果有人需要,这是一种方法。有点hack,但可以解决问题。您必须为所有视图设置足够大的 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() ) );
                }
            });
于 2011-11-24T11:27:32.887 回答
2

我知道这是一个老案例,但我有一个类似的问题,我ScrollView包含多个LinearLayouts,而它们又包含一个标题和一个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 使用方形图像,因此我将高度基于它们的宽度。我认为它不适用于灵活的网格项目高度。

于 2013-10-31T10:25:03.560 回答
1

显然,ScrollViews 中的 GridViews 在 Android 领域并不符合犹太教规。使用自定义行切换到 ListView。这似乎表现得更好。

于 2010-09-11T02:03:51.597 回答