Android ScrollView макет (wrap_content, максимальный размер) - PullRequest
4 голосов
/ 27 февраля 2012

Вот как бы я хотел, чтобы мой ScrollView выглядел так:

  • Максимальный размер определяется с помощью layout_weight (чтобы другие элементы под ScrollView могли отображаться правильно)
  • Если содержимое меньше этого максимального размера, оно просто ведет себя как с layout_height="wrap_content"

Вот что у меня сейчас есть:

<ScrollView
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:measureAllChildren="true"
            android:fillViewport="false"
            >

Я не думаю, что measureAllChildren действительно вообще что-то делает ...

Если я добавлю android:layout_weight, размер всегда будет таким, каким я бы хотел быть максимальным. Без этого он просто расширяется больше, чем должен ...

Я не против расширения класса ScrollView для изменения поведения onMeasure, если мне нужно ...?

PS: Если это что-то меняет, я пытаюсь заставить это работать с Froyo и далее.

Ответы [ 4 ]

7 голосов
/ 13 марта 2012

Я закончил писать свой собственный класс, расширяющий ScrollView

Так как вы спросите ... вот код.Возможно, не самый чистый, но он делает то, что я хочу.

Обратите внимание, что он ожидает, что layout_weight будет установлен при создании представления, и вы не должны устанавливать weigthSum в родительском LinearLayout, иначе вы получите забавные вещи (так как вес этого изменяется от исходного значения до 0 в зависимости от размера содержимого ScrollView)

Во-первых, в файле макета представление объявляется так:

<com.matthieu.widget.ShrinkingScrollView
    android:id="@+id/scroll"
    android:scrollbars="vertical"
    android:layout_height="0dp"
    android:layout_width="fill_parent"
    android:layout_weight="4"
    android:background="#cc0000"
    >
    <TextView
        android:id="@+id/in_scroll_view"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:background="#0000bb"
        />
</com.matthieu.widget.ShrinkingScrollView>

Тогда код для виджета:

import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.ScrollView;

public class ShrinkingScrollView extends ScrollView {
    private float original_weight=-1;
    public ShrinkingScrollView(Context context) {
        super(context);
    }

    public ShrinkingScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ShrinkingScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
        float previous_weight = params.weight;

        if (original_weight == -1)
            original_weight = params.weight;

        if ((getChildCount()>0) && (getVisibility()!=GONE)) {
            super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED));
            int overall_height = getChildAt(0).getMeasuredHeight();
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (getMeasuredHeight() >= overall_height) {
                if (previous_weight != 0) {
                    params.weight=0;
                    params.height = overall_height;
                    setLayoutParams(params);
                    post(new Runnable() {
                        public void run() {
                            requestLayout();
                        }
                    });
                }

                setMeasuredDimension(getMeasuredWidth(),overall_height);
            }
            else if (previous_weight == 0) {
                params.weight = original_weight;
                params.height = 0;
                setLayoutParams(params);
                post(new Runnable() {
                    public void run() {
                        requestLayout();
                    }
                });
            }
        }
        else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}
0 голосов
/ 25 ноября 2017

Ответ JMpergar кажется правильным, но он не работал, пока я не изменил метод onMeasure, как показано ниже.

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        try {
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
            if (maxHeight != WITHOUT_MAX_HEIGHT_VALUE
                    && heightSize > maxHeight) {
                heightSize = maxHeight;
                heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
                getLayoutParams().height = heightSize;

            } else {
                heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
                setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec)
                        , getDefaultSize(this.getSuggestedMinimumHeight(), heightMeasureSpec));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
0 голосов
/ 05 ноября 2014

Здесь другое решение, использующее размеры вместо весов.Я расширил ScrollView и добавил код для реализации этой функции:

https://gist.github.com/JMPergar/439aaa3249fa184c7c0c

Надеюсь, это будет полезно.

0 голосов
/ 27 февраля 2012

Если я правильно понимаю ваше требование, то, как я сделал что-то вроде этого, поместил вид прокрутки вместе со всем, что вы хотите отобразить под ним, в Относительный макет. Затем в файле макета сначала поместите элемент в нижней части экрана в файле (с помощью android: layout_alignParentBottom = "true"), затем поместите представление прокрутки и поместите его над первым элементом, используя что-то вроде: android: layout_above = "@ идентификатор / firstItem". Вот так, в котором я поместил вид изображения внизу с видом прокрутки над ним, занимая оставшееся пространство:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/searchByNameScreen"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="1dip"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/bottomImage"
        android:layout_width="fill_parent"
        android:layout_height="75dip"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:paddingBottom="15dip"
        android:paddingLeft="10dip"
        android:paddingRight="10dip"
        android:paddingTop="7dip"
        android:scaleType="fitXY"
        android:src="@drawable/android_450x50_moreinfo" />

    <ScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ScrollView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/bottomImage"
        android:layout_marginBottom="3dip"
        android:layout_marginLeft="10dip"
        android:layout_marginRight="10dip"
        android:layout_marginTop="1dip"
        android:scrollbars="none" >

        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/aboutCopyLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/aboutTopLayer"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/rounded_background"
            android:gravity="center"
            android:padding="5dip" >

            <!-- android:background="@drawable/rounded_background" -->

            <TextView
                android:id="@+id/aboutCopyText"
                style="@style/ResortNameExtraLine"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:gravity="center_horizontal"
                android:text="@string/aboutCopy" />
        </LinearLayout>
    </ScrollView>
</RelativeLayout>
...