Android: почему нет maxHeight для просмотра? - PullRequest
163 голосов
/ 29 октября 2010

В представлениях есть minHeight, но почему-то не хватает maxHeight:

Я пытаюсь добиться того, чтобы некоторые элементы (представления) заполняли ScrollView,Когда есть элементы 1..3, я хочу отобразить их напрямую.Значение ScrollView имеет высоту 1, 2 или 3 элементов.

Когда есть 4 или более элементов, я хочу, чтобы ScrollView прекратил расширение (таким образом, maxHeight) и начал обеспечивать прокрутку..

Однако, к сожалению, нет способа установить maxHeight.Поэтому мне, вероятно, придется программно установить мою высоту ScrollView на WRAP_CONTENT при наличии элементов 1,3 и высоту на 3*sizeOf(View) при наличии 4 или более элементов.

Может кто-нибудь объяснитьпочему нет maxHeight, если уже есть minHeight?

(Кстати: в некоторых видах, например, ImageView, реализовано maxHeight.)

Ответы [ 14 ]

78 голосов
/ 12 мая 2014

Ни одно из этих решений не работало для того, что мне было нужно, для ScrollView было установлено значение wrap_content, но имел maxHeight, чтобы он прекратил расширение после определенной точки и начал прокрутку. Я просто переопределил метод onMeasure в ScrollView.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(300, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

Это может работать не во всех ситуациях, но, безусловно, дает мне результаты, необходимые для моего макета. И это также обращается к комментарию Madhu.

Если какой-то макет присутствует под видом прокрутки, этот трюк не сработает - madhu 5 марта в 4: 36

68 голосов
/ 11 декабря 2012

Чтобы создать ScrollView или ListView с maxHeight, вам просто нужно создать прозрачный LinearLayout вокруг него с высотой, которую вы хотите, чтобы maxHeight был. Затем вы устанавливаете высоту ScrollView на wrap_content. Это создает ScrollView, который, кажется, растет, пока его высота не станет равной родительскому LinearLayout.

35 голосов
/ 21 ноября 2015

Это помогло мне настроить его в xml:

MaxHeightScrollView.java:

public class MaxHeightScrollView extends ScrollView {

private int maxHeight;
private final int defaultHeight = 200;

public MaxHeightScrollView(Context context) {
    super(context);
}

public MaxHeightScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

private void init(Context context, AttributeSet attrs) {
    if (attrs != null) {
        TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        //200 is a defualt value
        maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_maxHeight, defaultHeight);

        styledAttrs.recycle();
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

attr.xml

<declare-styleable name="MaxHeightScrollView">
        <attr name="maxHeight" format="dimension" />
    </declare-styleable>

пример макета

<blah.blah.MaxHeightScrollView android:layout_weight="1"
                app:maxHeight="90dp"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">
                <EditText android:id="@+id/commentField"
                    android:hint="Say Something"
                    android:background="#FFFFFF"
                    android:paddingLeft="8dp"
                    android:paddingRight="8dp"
                    android:gravity="center_vertical"
                    android:maxLines="500"
                    android:minHeight="36dp"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" />
            </blah.blah.MaxHeightScrollView>
11 голосов
/ 24 февраля 2018

(я знаю, что это не дает прямого ответа на вопрос, но может быть полезно для других, ищущих функциональность maxHeight)

ConstraintLayout предлагает максимальную высоту для своих детей через

app:layout_constraintHeight_max="300dp"
app:layout_constrainedHeight="true" 

или

app:layout_constraintWidth_max="300dp"
app:layout_constrainedWidth="true" 

Пример использования здесь .

7 голосов
/ 14 ноября 2016

Я бы прокомментировал ответ Whizzle, если бы мог, но посчитал полезным отметить, что для того, чтобы решить эту проблему в контексте многооконного режима в Android N, мне нужно было немного изменить код :

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if(MeasureSpec.getSize(heightMeasureSpec) > maxHeight) {
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

Это позволяет изменить размер макета, чтобы он был меньше максимальной высоты, но также не позволяет ему быть больше, чем максимальная высота. Я использовал этот класс макета, который переопределяет RelativeLayout, и это позволило мне создать собственный диалог с ScrollView в качестве дочернего элемента MaxHeightRelativeLayout, который не расширяет всю высоту экрана, а также сжимается, чтобы вписаться наименьший размер вдовы в мультиокне для Android N.

3 голосов
/ 21 февраля 2018

Мой MaxHeightScrollView Пользовательский вид

public class MaxHeightScrollView extends ScrollView {
    private int maxHeight;

    public MaxHeightScrollView(Context context) {
        this(context, null);
    }

    public MaxHeightScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray styledAttrs =
                context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        try {
            maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_mhs_maxHeight, 0);
        } finally {
            styledAttrs.recycle();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

style.xml

<declare-styleable name="MaxHeightScrollView">
    <attr name="mhs_maxHeight" format="dimension" />
</declare-styleable>

Использование

<....MaxHeightScrollView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:mhs_maxHeight="100dp"
    >

    ...

</....MaxHeightScrollView>
3 голосов
/ 20 апреля 2012

Нет способа установить maxHeight.Но вы можете установить высоту.

. Для этого вам потребуется определить высоту каждого элемента вашего scrollView.После этого просто установите высоту scrollView на numberOfItens * heightOfItem.

Чтобы определить высоту элемента, сделайте следующее:

View item = adapter.getView(0, null, scrollView);
item.measure(0, 0);
int heightOfItem = item.getMeasuredHeight();

Чтобы установить высоту, сделайте это:

1 голос
/ 25 апреля 2018

Оберните ваш ScrollView вокруг вашей простой LinearLayout с layout_height = "max_height", это отлично подойдет. На самом деле, у меня есть этот код в производстве за последние 5 лет с нулевыми проблемами.

<LinearLayout
        android:id="@+id/subsParent"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:gravity="bottom|center_horizontal"
        android:orientation="vertical">

        <ScrollView
            android:id="@+id/subsScroll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:layout_marginEnd="15dp"
            android:layout_marginStart="15dp">

            <TextView
                android:id="@+id/subsTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/longText"
                android:visibility="visible" />

        </ScrollView>
    </LinearLayout>
1 голос
/ 01 ноября 2012

Если кто-то рассматривает возможность использования точного значения для LayoutParams, например,

setLayoutParams(new LayoutParams(Y, X );

Не забудьте учесть плотность отображения устройства, в противном случае вы можете получить очень странное поведение на разных устройствах. Например:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics d = new DisplayMetrics();
display.getMetrics(d);
setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, (int)(50*d.density) ));
1 голос
/ 09 марта 2012

Как мы знаем, устройства под управлением Android могут иметь разные размеры экрана.Как мы также знаем, виды должны корректироваться динамически и становиться подходящим пространством.

Если вы установите максимальную высоту, вы можете заставить вид не занимать достаточно места или занимать меньше места.Я знаю, что иногда кажется, что практически установить максимальную высоту.Но если разрешение когда-либо резко изменится, и оно изменится !, то представление, имеющее максимальную высоту, будет выглядеть неуместно.

Я думаю, что не существует правильного способа точно выполнить макет, который вы хотите.Я бы порекомендовал вам продумать макет, используя менеджеры макетов и соответствующие механизмы.я не знаю, чего вы пытаетесь достичь, но мне немного странно, что в списке должны отображаться только три элемента, а затем пользователь должен прокрутить.

btw.minHeight не гарантируется (и, возможно, не должно существовать).это может иметь некоторое преимущество, чтобы заставить элементы быть видимыми, в то время как другие относительные элементы становятся меньше.

...