Android: dlaczego nie ma wartości maxHeight dla widoku?

184

Widoki mają,minHeight ale jakoś brakuje maxHeight:

To, co próbuję osiągnąć, to wypełnienie niektórych elementów (widoków) ScrollView. Kiedy jest 1..3 elementów, chcę je wyświetlić bezpośrednio. Oznacza to, że ScrollViewma wysokość 1, 2 lub 3 elementów.

Gdy są 4 lub więcej elementów, chcę, ScrollViewaby przestał się rozwijać (a więc a maxHeight) i zaczął przewijać.

Niestety nie ma sposobu, aby ustawić maxHeight. Prawdopodobnie więc muszę ScrollViewprogramowo ustawić swoją wysokość na WRAP_CONTENT1 lub 3 elementy i ustawić wysokość na 3*sizeOf(View)4 lub więcej pozycji.

Czy ktoś może wyjaśnić, dlaczego nie ma maxHeight, skoro już istnieje minHeight?

(BTW: niektóre widoki, na przykład ImageViewmają maxHeightzaimplementowane.)

znq
źródło
Opublikowałem rozwiązanie w innym wątku: stackoverflow.com/questions/18425758/...
JMPergar
2
Stworzyłem rozwiązanie tego na chintanrathod.com/…
Chintan Rathod
Usunięcie przez Google maxHeight jest denerwujące i niewygodne. Spójrz na wszystkie rzeczy, które musisz teraz zrobić, aby uzyskać ten sam wynik.
Ian Wambai

Odpowiedzi:

86

Żadne z tych rozwiązań nie działało tak, jak potrzebowałem, czyli ScrollView ustawiony na wrap_content, ale posiadający maxHeight, aby przestał się rozwijać po pewnym momencie i zaczął przewijać. Po prostu przesłoniłem metodę onMeasure w ScrollView.

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

To może nie działać we wszystkich sytuacjach, ale z pewnością daje mi wyniki potrzebne do mojego układu. I odnosi się również do komentarza madhu.

Jeśli jakiś układ znajduje się poniżej widoku przewijania, ta sztuczka nie zadziała - madhu 5 marca o 4:36

gwizdać
źródło
1
Kiedy to nie zadziała? To wydaje się bardzo czystym rozwiązaniem. Zastanawiam się, dlaczego nie zaimplementowali go w xml.
Christophe Smet
1
Prawdopodobnie nie zadziałałoby, jeśli ręcznie ustawiłeś wysokość na 240. Nie zawracałem sobie głowy sprawdzaniem trybu, w którym znajduje się scrollview, ponieważ potrzebowałem tylko obsługiwać 1 określony tryb (wrap_content).
świst
Istnieje edycja tej odpowiedzi, która mówi: „Jeśli jakiś układ znajduje się poniżej widoku przewijania, to ta sztuczka nie zadziała”, co nie jest prawdą. Mam układ wyrównany do dolnej części strony, a ten niestandardowy układ ma „android: layout_above = '@ + ...'”, co zawsze umieszcza niestandardowy układ nad dolnym układem :)
Machine Tribe
70

W celu stworzenia ScrollViewlub ListViewz maxheight wystarczy stworzyć Transparent LinearLayout wokół niego o wysokości co chcesz maxheight być. Następnie ustaw Wysokość ScrollView na wrap_content. Spowoduje to utworzenie ScrollView, który wydaje się rosnąć, dopóki jego wysokość nie będzie równa nadrzędnemu LinearLayout.

JustinMorris
źródło
3
Było to przydatne, aby zapobiec rozszerzeniu okna dialogowego z przewijaną zawartością do pełnej wysokości ekranu.
Kyle Ivey
Niewielką sugestią byłoby użycie FrameLayout zamiast LinearLayout, ale wątpię, czy to ma znaczenie.
Kyle Ivey
43
Jeśli jakiś układ znajduje się poniżej widoku przewijania, ta sztuczka nie zadziała
Sreedhu Madhu
2
czy możesz podać kod? nie działało to dla mnie, więc może robię coś złego ...
programista Androida
nie będzie działać, jeśli masz pod nim przyciski. zepchnie przyciski z ekranu
Li Tian Gong
43

To działało dla mnie, aby dostosować go do formatu 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>

przykładowy układ

<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>
SlickDev
źródło
Utworzenie niestandardowego widoku jest zdecydowanie najlepszym sposobem na osiągnięcie tego.
Bertram Gilfoyle,
I to działa, jeśli masz układ poniżej widoku przewijania! Idealny!
Ragaisis
25

(Wiem, że nie odpowiada to bezpośrednio na pytanie, ale może być pomocne dla innych osób poszukujących funkcjonalności maxHeight)

ConstraintLayout oferuje swoim dzieciom maksymalną wysokość

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

lub

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

Przykładowe użycie tutaj .

użytkownik1506104
źródło
2
To nie działa, jeśli widok jest w łańcuchu pionowym (jak określono w dokumentach ConstraintLayout)
Arno Schoonbee
Dzięki za informację.
user1506104
8

Skomentowałbym odpowiedź gwizdka, gdybym mógł, ale pomyślałem, że warto zauważyć, że aby rozwiązać ten problem w kontekście trybu wielu okien w Androidzie N, musiałem nieco zmienić kod na ten:

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

Pozwala to na zmianę rozmiaru układu na mniejszą niż maksymalna wysokość, ale także zapobiega jego zwiększeniu powyżej maksymalnej wysokości. Użyłem tej klasy układu, która zastępuje, RelativeLayoutco pozwoliło mi stworzyć niestandardowe okno dialogowe z ScrollViewdzieckiem, MaxHeightRelativeLayoutktóre nie rozszerza pełnej wysokości ekranu, a także kurczy się, aby zmieścić się w najmniejszym rozmiarze wdowy w wielu oknach dla Androida N.

JP Krause
źródło
4

Nie ma możliwości ustawienia maxHeight. Ale możesz ustawić Wysokość.

Aby to zrobić, musisz odkryć wysokość każdego elementu przewijania scrollView. Następnie ustaw wysokość scrollView na numberOfItens * heightOfItem.

Aby odkryć wysokość przedmiotu, wykonaj następujące czynności:

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

Aby ustawić wysokość:

// if the scrollView already has a layoutParams:
scrollView.getLayoutParams().height = heightOfItem * numberOfItens;
// or
// if the layoutParams is null, then create a new one.
scrollView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, heightOfItem * numberOfItens));
Derzu
źródło
4

Zawiń się ScrollViewwokół równiny LinearLayoutz layout_height = "max_height", to zrobi idealną robotę. W rzeczywistości mam ten kod w produkcji z ostatnich 5 lat bez problemów.

<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>
Sai
źródło
1
Rzeczywiście idealne rozwiązanie. Sprytny i prosty. Nadaje się nawet do recyklingu.
Alex Belets
3

Mój MaxHeightScrollViewniestandardowy widok

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>

Za pomocą

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

    ...

</....MaxHeightScrollView>
Phan Van Linh
źródło
2

Mam tutaj odpowiedź:

https://stackoverflow.com/a/29178364/1148784

Wystarczy utworzyć nową klasę rozszerzającą ScrollView i zastąpić jej onMeasuremetodę.

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0){
            int hSize = MeasureSpec.getSize(heightMeasureSpec);
            int hMode = MeasureSpec.getMode(heightMeasureSpec);

            switch (hMode){
                case MeasureSpec.AT_MOST:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.AT_MOST);
                    break;
                case MeasureSpec.UNSPECIFIED:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
                    break;
                case MeasureSpec.EXACTLY:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.EXACTLY);
                    break;
            }
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
babay
źródło
2

Jak wspomniano powyżej, ConstraintLayout oferuje swoim dzieciom maksymalną wysokość poprzez:

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

Poza tym, jeśli maksymalna wysokość dla jednego dziecka ConstraintLayout nie jest pewna do momentu uruchomienia aplikacji, nadal istnieje sposób, aby to dziecko automatycznie dostosowało zmienną wysokość bez względu na to, gdzie zostało umieszczone w pionowym łańcuchu.

Na przykład musimy wyświetlić dolne okno dialogowe ze zmiennym nagłówkiem TextView, zmiennym ScrollView i zmienną stopką TextView. Maksymalna wysokość okna dialogowego wynosi 320dp, gdy całkowita wysokość nie osiąga 320dp ScrollView działa jak zawartość_zawija, gdy całkowita wysokość przekracza ScrollView działa jako „maxHeight = 320dp - wysokość nagłówka - wysokość stopki”.

Możemy to osiągnąć tylko poprzez plik układu xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="320dp">

    <TextView
        android:id="@+id/tv_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/black_10"
        android:gravity="center"
        android:padding="10dp"
        app:layout_constraintBottom_toTopOf="@id/scroll_view"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintVertical_chainStyle="packed"
        tools:text="header" />

    <ScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/black_30"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@id/tv_footer"
        app:layout_constraintHeight_max="300dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_header">

        <LinearLayout
            android:id="@+id/ll_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_sub1"
                android:layout_width="match_parent"
                android:layout_height="160dp"
                android:gravity="center"
                android:textColor="@color/orange_light"
                tools:text="sub1" />

            <TextView
                android:id="@+id/tv_sub2"
                android:layout_width="match_parent"
                android:layout_height="160dp"
                android:gravity="center"
                android:textColor="@color/orange_light"
                tools:text="sub2" />

        </LinearLayout>
    </ScrollView>

    <TextView
        android:id="@+id/tv_footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/black_50"
        android:gravity="center"
        android:padding="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/scroll_view"
        tools:text="footer" />
</android.support.constraint.ConstraintLayout>

Większość kodów importowych jest krótka:

app:layout_constraintVertical_bias="1"
app:layout_constraintVertical_chainStyle="packed"

app:layout_constrainedHeight="true"

Poziomy poziom maksymalnego wykorzystania jest taki sam.

xionghg
źródło
1

Czy próbowałeś użyć wartości layout_weight ? Jeśli ustawisz jeden na wartość większą niż 0, rozciągnie ten widok na pozostałą dostępną przestrzeń.

Jeśli miałeś wiele widoków, które musiały zostać rozciągnięte, wówczas wartość stanie się wagą między nimi.

Więc jeśli miałbyś dwa widoki ustawione na wartość weight_weight 1, wówczas oba rozciągałyby się, aby wypełnić przestrzeń, ale oba rozciągałyby się na równą ilość miejsca. Jeśli ustawisz jedną z nich na wartość 2, rozciągnie się ona dwa razy bardziej niż drugi widok.

Kilka dodatkowych informacji tutaj wymienionych w części Układ liniowy.

Bryan Denny
źródło
1
Problem z wagami polega na tym, że są względne. Różne rozmiary ekranu, różne wyniki, np. Przy ekranie o rozdzielczości 800 pikseli, mogę ustawić wagę do określonej wartości, tak aby określony obszar skończył się pożądaną wartością 200 pikseli. Jednak w przypadku ekranu o rozdzielczości 850 pikseli konkretny obszar jest większy niż 200 pikseli, ale dołączone elementy nadal mają tylko 200 pikseli. Dlatego wolałem mieć, maxHeightktóry mogę ustawić na konkretną wartość spadku. (W końcu skończyłem na obliczeniach i programowo ustawiłem wysokości)
znq
1

Myślę, że możesz ustawić wysokość w czasie wykonywania dla 1 elementu tylko scrollView.setHeight(200px)dla 2 elementów scrollView.setheight(400px)dla 3 lub więcejscrollView.setHeight(600px)

Yayo28
źródło
8
Nie chcesz ustawiać wymiaru w „px”. Jest bardzo prawdopodobne, że nie uzyskasz pożądanego rezultatu na wielu urządzeniach. developer.android.com/guide/topics/resources/…
Hernd DerBeld
@HerndDerBeld tak to działa w kodzie. jeśli chcesz, zawsze możesz dość łatwo przekonwertować z DP na piksele: float pixel = TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources () .getDisplayMetrics ());
programista Androida
1

Jak wiemy, urządzenia z Androidem mogą mieć różne rozmiary ekranu. Jak dalej wiemy, widoki powinny dostosowywać się dynamicznie i stać się odpowiednią przestrzenią.

Jeśli ustawisz maksymalną wysokość, możesz zmusić widok, aby nie miał wystarczającej ilości miejsca lub zajął mniej miejsca. Wiem, że czasami wydaje się, że praktycznie można ustawić maksymalną wysokość. Ale jeśli rozdzielczość kiedykolwiek zmieni się drastycznie i będzie !, widok o maksymalnej wysokości nie będzie wyglądał odpowiednio.

myślę, że nie ma właściwego sposobu, aby dokładnie zrobić pożądany układ. zaleciłbym przemyślenie układu za pomocą menedżerów układu i mechanizmów względnych. nie wiem, co próbujesz osiągnąć, ale dla mnie to trochę dziwne, że lista powinna zawierać tylko trzy elementy, a następnie użytkownik musi przewijać.

btw. minHeight nie jest gwarantowany (i może też nie powinien istnieć). może mieć pewne zalety wymuszania widoczności przedmiotów, podczas gdy inne względne przedmioty stają się mniejsze.

Diego Frehner
źródło
6
To jest źle. Zgodnie z tą logiką nie można również powiedzieć android: layout_width = "500dp".
Glenn Maynard
Nie rozumiem, co powinno być nie tak, ani twojej logicznej interpretacji. Jeśli ustawisz layout_width (co czasami jest w porządku), nie ma gwarancji, że to otrzymasz. 500dp może wyglądać na jednym odpowiednim urządzeniu, na innym nie. Menedżerowie układów ftw! Może mógłbyś wyjaśnić więcej bcs przeszkadza głosowanie w dół :)
Diego Frehner
3
Równie ważne jest powiedzenie android: maxWidth = "500dp", jak powiedzenie android: layout_width = "500dp". Oba wymuszają określone wymiary na widoku.
Glenn Maynard
1

Jeśli ktoś rozważa użycie dokładnej wartości dla LayoutParams np

setLayoutParams(new LayoutParams(Y, X );

Pamiętaj, aby wziąć pod uwagę gęstość wyświetlacza urządzenia, w przeciwnym razie możesz uzyskać bardzo dziwne zachowanie na różnych urządzeniach. Na przykład:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics d = new DisplayMetrics();
display.getMetrics(d);
setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, (int)(50*d.density) ));
Nicklas Gnejs Eriksson
źródło
0

Najpierw uzyskaj wysokość przedmiotu w pikselach

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

to po prostu

Display display = getWindowManager().getDefaultDisplay();    
DisplayMetrics displayMetrics = new DisplayMetrics();    
display.getMetrics(displayMetrics);    
scrollView.getLayoutParams().height = (int)((heightOfItem * 3)*displayMetrics .density);
Ibrahim Khaled
źródło
0

jeśli chcecie zrobić widok przewijania lub listy bez przepełnienia, po prostu na RelativeLayout z widokiem od góry i od dołu u góry i u dołu:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/topview"
    android:layout_below="@+id/bottomview" >
Quoc Duy Nguyen
źródło
To wymaga więcej kredytu. Specyficzna, ale prosta implementacja.
Luke Allison
0

Użyłem niestandardowego ScrollView wykonanego w Kotlin, który używa maxHeight. Przykład zastosowania:

<com.antena3.atresplayer.tv.ui.widget.ScrollViewWithMaxHeight
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:maxHeight="100dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
</com.antena3.atresplayer.tv.ui.widget.ScrollViewWithMaxHeight>

Oto kod ScrollViewWidthMaxHeight:

import android.content.Context
import android.util.AttributeSet
import android.widget.ScrollView
import timber.log.Timber

class ScrollViewWithMaxHeight @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ScrollView(context, attrs, defStyleAttr) {

companion object {
    var WITHOUT_MAX_HEIGHT_VALUE = -1
}

private var maxHeight = WITHOUT_MAX_HEIGHT_VALUE

init {
    val a = context.obtainStyledAttributes(
        attrs, R.styleable.ScrollViewWithMaxHeight,
        defStyleAttr, 0
    )
    try {
        maxHeight = a.getDimension(
            R.styleable.ScrollViewWithMaxHeight_android_maxHeight,
            WITHOUT_MAX_HEIGHT_VALUE.toFloat()
        ).toInt()
    } finally {
        a.recycle()
    }
}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    var heightMeasure = heightMeasureSpec
    try {
        var heightSize = MeasureSpec.getSize(heightMeasureSpec)
        if (maxHeight != WITHOUT_MAX_HEIGHT_VALUE) {
            heightSize = maxHeight
            heightMeasure = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST)
        } else {
            heightMeasure = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.UNSPECIFIED)
        }
        layoutParams.height = heightSize
    } catch (e: Exception) {
        Timber.e(e, "Error forcing height")
    } finally {
        super.onMeasure(widthMeasureSpec, heightMeasure)
    }
}

fun setMaxHeight(maxHeight: Int) {
    this.maxHeight = maxHeight
}
}

który potrzebuje również tej deklaracji w values/attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScrollViewWithMaxHeight">
        <attr name="android:maxHeight" />
    </declare-styleable>
</resources>
Mario Velasco
źródło