Как установить максимальную высоту с содержимым обертки в android?

В android, как вы можете создать представление прокрутки, которое получило максимальную высоту, и обернуть содержимое, в основном оно обертывает содержимое по вертикали, но имеет максимальную высоту?

Я пробовал

<ScrollView 
     android:id="@+id/scrollView1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
         android:maxHeight="200dp"
     android:layout_alignParentBottom="true" >

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

    </LinearLayout>
</ScrollView>

Но это не работает?

Ответ 1

вы можете добавить это в любое представление (переопределить onMeasure в классе, унаследованном от представления)

@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);
}

Ответ 3

Вы можете сделать это программно.

 private static class OnViewGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
    private final static int maxHeight = 130;
    private View view;

    public OnViewGlobalLayoutListener(View view) {
        this.view = view;
    }

    @Override
    public void onGlobalLayout() {
        if (view.getHeight() > maxHeight)
            view.getLayoutParams().height = maxHeight;
    }
}

И добавьте слушателя в представление:

view.getViewTreeObserver()
                  .addOnGlobalLayoutListener(new OnViewGlobalLayoutListener(view));

Listener вызовет метод onGlobalLayout(), когда высота представления будет изменена.

Ответ 4

для установки высоты прокрутки вы должны использовать 2 linerlayout внутри вместе, а затем установить scrool view в качестве их потомка, а затем установить средний макет linerlayout: высота для ограничения высоты прокрутки.

Ответ 5

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

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var tempHeightMeasureSpec = heightMeasureSpec
        var tempWidthMeasureSpec = widthMeasureSpec

        fun getSize(size: Int, maxSize: Int): Int {
            val hSize = View.MeasureSpec.getSize(size)
            val hMode = View.MeasureSpec.getMode(size)

            if (maxSize <= 0) return hSize

            return when (hMode) {
                View.MeasureSpec.AT_MOST -> Math.min(hSize, maxHeight)
                View.MeasureSpec.UNSPECIFIED -> maxHeight
                View.MeasureSpec.EXACTLY -> Math.min(hSize, maxHeight)
                else -> hSize
            }
        }

        val hSize = View.MeasureSpec.getSize(tempHeightMeasureSpec)
        val wSize = View.MeasureSpec.getSize(tempWidthMeasureSpec)

        val newHeight = getSize(hSize, maxHeight)
        val newWidth = getSize(wSize, maxWidth)

        if (newHeight != hSize || wSize != newWidth)
            setMeasuredDimension(newWidth, newHeight)
        else
            super.onMeasure(tempWidthMeasureSpec, tempHeightMeasureSpec)

    }

Ответ 6

1.) Создайте класс для обработки установки максимальной высоты на то, что передается пользователем:

public class OnViewGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {


private Context context;
private int maxHeight;
private View view;

public OnViewGlobalLayoutListener(View view, int maxHeight, Context context) {
    this.context = context;
    this.view = view;
    this.maxHeight = dpToPx(maxHeight);
}

@Override
public void onGlobalLayout() {
    if (view.getHeight() > maxHeight) {
        ViewGroup.LayoutParams params = view.getLayoutParams();
        params.height = maxHeight;
        view.setLayoutParams(params);
    }
}

public int pxToDp(int px) {
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
    int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
    return dp;
}

public int dpToPx(int dp) {
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
    int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
    return px;
}
}

2.) Прикрепите это к виду и укажите максимальную высоту в DP:

messageBody.getViewTreeObserver()
            .addOnGlobalLayoutListener(
             new OnViewGlobalLayoutListener(messageBody, 256, context)
             );

Спасибо @harmashalex за вдохновение. Я внес изменения, так как установка параметров макета не работает с помощью кода @harma. Кроме того, преобразование dp в px необходимо для того, чтобы избавиться от сомнений в этом.

Ответ 7

Здесь вы можете установить высоту своего прокрутки, например:

<ScrollView 
 android:id="@+id/scrollView1"
 android:layout_width="match_parent"
 android:layout_height="200dp"
 android:layout_alignParentBottom="true" >

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

           </LinearLayout>
</ScrollView>