Как рассчитать требуемую высоту GridView, который находится внутри ScrollView на Android? - PullRequest
4 голосов
/ 10 сентября 2010

У меня есть GridView внутри LinearLayout внутри 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>

Ответы [ 3 ]

14 голосов
/ 24 ноября 2011

Вот один из способов сделать это, если кому-то это нужно. Немного взломать, но делает свое дело. Вы должны установить 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() ) );
                }
            });
2 голосов
/ 31 октября 2013

Я знаю, что это старый случай, но у меня была похожая проблема, когда мой 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 использует квадратные изображения, поэтому я основываю высоту на их ширине. Я не думаю, что это хорошо работает с гибкой высотой элементов сетки.

1 голос
/ 11 сентября 2010

Очевидно, что GridViews в ScrollViews не кошерны в Android-земле.Переключение на ListView с заказными строками.Это, кажется, ведет себя лучше.

...