Android:为什么视图没有maxHeight?

znq*_*znq 168 layout android view autoresize

View有一个minHeight但不知何故缺少一个maxHeight:

我想要实现的是让一些项目(视图)填满ScrollView.当有1..3项时,我想直接显示它们.意味着它ScrollView具有1,2或3个项目的高度.

当有4个或更多项目我希望ScrollView停止扩展(因此a maxHeight)并开始提供滚动.

但是,遗憾的是没有办法设置maxHeight.因此,我可能必须以ScrollView编程方式WRAP_CONTENT将高度设置为有1..3项3*sizeOf(View)时的高度,并将高度设置为有4个或更多项时的高度.

任何人都可以解释为什么没有maxHeight提供,什么时候已经有minHeight

(顺便说一下:有些观点,比如ImageView已经maxHeight实施了.)

whi*_*zle 79

这些解决方案都不适用于我需要的东西,这是ScrollView设置为wrap_content但是有一个maxHeight所以它会在某个点之后停止扩展并开始滚动.我只是简单地覆盖了ScrollView中的onMeasure方法.

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

这可能不适用于所有情况,但它确实给了我布局所需的结果.它也解决了madhu的评论.

如果滚动视图下面有一些布局,那么这个技巧就不会起作用 - madhu 3月5日4:36

  • 很好的技巧,只是不要忘记将dp转换为像素 (6认同)
  • 如果您手动将高度设置为 240,它可能不会起作用。我没有费心检查滚动视图所处的模式,因为我只需要支持 1 种特定模式 (wrap_content)。 (2认同)

Jus*_*ris 69

为了创建一个ScrollViewListView一个maxHeight,你只需要在它周围创建一个Transparent LinearLayout,其高度就是你想要的maxHeight.然后,将ScrollView的高度设置为wrap_content.这将创建一个ScrollView,它看起来会增长,直到其高度等于父LinearLayout.

  • 如果滚动视图下方有一些布局,则此技巧不起作用 (43认同)
  • 这对于防止滚动内容的对话框扩展到屏幕的整个高度非常有用. (3认同)
  • 你能提供一些代码吗?它不适合我,所以也许我做错了... (2认同)

Sli*_*Dev 39

这对我有用,可以在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);
}
}
Run Code Online (Sandbox Code Playgroud)

attr.xml

<declare-styleable name="MaxHeightScrollView">
        <attr name="maxHeight" format="dimension" />
    </declare-styleable>
Run Code Online (Sandbox Code Playgroud)

示例布局

<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>
Run Code Online (Sandbox Code Playgroud)


use*_*104 17

(我知道这不会直接回答这个问题,但可能对寻求maxHeight功能的其他人有所帮助)

ConstraintLayout为其孩子提供最大高度

app:layout_constraintHeight_max="300dp"
app:layout_constrainedHeight="true" 
Run Code Online (Sandbox Code Playgroud)

要么

app:layout_constraintWidth_max="300dp"
app:layout_constrainedWidth="true" 
Run Code Online (Sandbox Code Playgroud)

此处使用示例.

  • 如果视图在垂直链中(如ConstraintLayout文档中指定),则此方法不起作用 (2认同)

小智 8

如果可以的话,我会评论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);
}
Run Code Online (Sandbox Code Playgroud)

这允许布局调整大小小于最大高度,但也防止它大于最大高度.我用过这是一个Overrides的布局类,RelativeLayout这允许我创建一个自定义对话框,其中ScrollView的子窗口MaxHeightRelativeLayout不会扩展屏幕的整个高度,并且缩小到适合Android的多窗口中最小的窗口大小N.


小智 8

如上所述,ConstraintLayout 通过以下方式为其子项提供最大高度:

app:layout_constraintHeight_max="300dp"
app:layout_constrainedHeight="true"
Run Code Online (Sandbox Code Playgroud)

此外,如果一个 ConstraintLayout 的 child 的最大高度在 App 运行之前是不确定的,那么仍然有办法让这个 child 自动适应一个可变的高度,不管它放在垂直链的什么地方。

例如,我们需要显示一个底部对话框,其中包含一个可变标题 TextView、一个可变 ScrollView 和一个可变页脚 TextView。对话框的最大高度为 320dp?当总高度未达到 320dp 时 ScrollView 充当 wrap_content,当总高度超过 ScrollView 时充当“maxHeight=320dp - 页眉高度 - 页脚高度”。

我们可以通过 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>
Run Code Online (Sandbox Code Playgroud)

大多数导入代码都很短:

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

app:layout_constrainedHeight="true"
Run Code Online (Sandbox Code Playgroud)

水平 maxWidth 的用法完全相同。


Bry*_*nny 1

您是否尝试过使用layout_weight值?如果将其设置为大于 0 的值,它将将该视图拉伸到剩余的可用空间。

如果您有多个视图需要拉伸,那么该值将成为它们之间的权重。

因此,如果两个视图的layout_weight值都设置为1,那么它们都会拉伸以填充空间,但它们都会拉伸到相同的空间量。如果将其中一个视图的值设置为 2,那么它将拉伸为另一个视图的两倍。

线性布局下列出了更多信息。