安卓:为什么View没有maxHeight属性?

206

View有一个minHeight,但一些View却缺少了maxHeight:

我想实现的是让一些项目(View)填充一个ScrollView。当有1..3个项目时,我希望它们直接显示在屏幕上,也就是ScrollView的高度为1、2或3个项目。

当有4个或更多项目时,我希望ScrollView停止扩展(即有一个maxHeight),并开始提供滚动。

然而,很不幸地是没有办法设置maxHeight。因此,我可能需要根据情况在程序中将ScrollView的高度设置为WRAP_CONTENT,当有1..3个项目时,将高度设置为3*sizeOf(View),当有4个或更多项目时。

有人能解释为什么已经有minHeight,为什么没有提供maxHeight吗?

(顺便说一下:一些View,比如ImageView,已经实现了maxHeight。)


我在另一个帖子中发布了解决方案:https://dev59.com/zWMl5IYBdhLWcg3wZWWE#26758657 - JMPergar
2
我已经在http://chintanrathod.com/maxheightscrollview-in-android-using-android-studio/上为此创建了一个解决方案。 - Chintan Rathod
谷歌移除maxHeight真是令人烦恼和不便。现在你必须做很多事情才能得到相同的结果。 - Ian Wambai
18个回答

2

如果有人需要的话:

app:layout_constraintHeight_max="300dp"

这会强制 ConstraintLayout 中的 View 最大高度为 300dp。如果您想以编程方式实现此操作,可以按照以下方式进行:

val totalScreenHeight = displayMetrics.heightPixels
val layoutParams: ConstraintLayout.LayoutParams = viewThatIsInsideAConstraintLayout.layoutParams as ConstraintLayout.LayoutParams
        layoutParams.matchConstraintMaxHeight = totalScreenHeight/2
viewThatIsInsideAConstraintLayout.layoutParams = layoutParams

1
首先以像素为单位获取项目的高度。
View rowItem = adapter.getView(0, null, scrollView);   
rowItem.measure(0, 0);    
int heightOfItem = rowItem.getMeasuredHeight();

然后只需简单地

Display display = getWindowManager().getDefaultDisplay();    
DisplayMetrics displayMetrics = new DisplayMetrics();    
display.getMetrics(displayMetrics);    
scrollView.getLayoutParams().height = (int)((heightOfItem * 3)*displayMetrics .density);

1

如果有人考虑使用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

正如我们所知,运行Android的设备可能具有不同的屏幕尺寸。我们进一步了解到视图应该动态调整并成为适当的空间。

如果您设置最大高度,您可能会强制视图不获得足够的空间或占用过少的空间。我知道有时候设置最大高度似乎是实际的。但是,如果分辨率发生巨大变化,而且它将会发生!那么具有最大高度的视图将看起来不合适。

我认为没有确切的方法可以完全按照您想要的布局进行操作。我建议您使用布局管理器和相对机制来考虑您的布局。我不知道您想要实现什么,但对我来说,列表只显示三个项目,然后用户必须滚动听起来有点奇怪。

顺便说一句,minHeight不能保证(也许也不应该存在)。它可以在其他相关项变小的同时强制某些项可见。


7
这是错误的。按照这种逻辑,你也不能说android:layout_width="500dp"。 - Glenn Maynard
我不明白哪里出了问题,也不理解你的逻辑解释。如果你设置layout_width(有时是可以的),并不能保证你会得到那个值。500dp在一个设备上可能看起来合适,在另一个设备上可能不合适。布局管理器才是王道!或许你可以多解释一些,因为这个踩踏让人困扰 :) - Diego Frehner
3
说android:maxWidth="500dp"和android:layout_width="500dp"都是有效的,它们都强制给视图一个特定的尺寸。 - Glenn Maynard

1

你尝试过使用layout_weight value吗?如果将其设置为大于0的值,则会将该视图拉伸到剩余可用空间。

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

因此,如果您有两个视图都设置为1的layout_weight值,则它们都会拉伸以填充空间,但它们会均匀地拉伸相同数量的空间。如果将其中一个设置为2,则它将比另一个视图拉伸两倍。

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


1
权重的问题在于它们是相对的。不同的屏幕尺寸,不同的结果,例如,在800像素的屏幕上,我可以将权重设置为特定值,以便特定区域最终达到所需的200像素。然而,在850像素的屏幕上,特定区域的大小超过了200像素,但包含的元素仍然只有200像素。这就是为什么我更喜欢有一个maxHeight,我可以将其设置为特定的dip值。(最终我计算并以编程方式设置高度) - znq

1
我认为你可以在运行时设置每个项目的高度,只需使用 scrollView.setHeight(200px) 来设置1个项目的高度,对于2个项目,使用 scrollView.setheight(400px),对于3个或更多项目,使用 scrollView.setHeight(600px)

9
不要使用“px”作为尺寸单位,因为在多种设备上很可能得不到想要的结果。请参考http://developer.android.com/guide/topics/resources/more-resources.html#Dimension。 - Hernd DerBeld
@HerndDerBeld 这就是代码中的工作方式。如果您希望,您可以很容易地从DP转换为像素:float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); - android developer

1

我使用了一个用 Kotlin 制作的 自定义 ScrollView,它使用了 maxHeight。使用示例:

<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>

这里是 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
}
}

还需要在values/attrs.xml中进行声明:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScrollViewWithMaxHeight">
        <attr name="android:maxHeight" />
    </declare-styleable>
</resources>

R.styleable.ScrollViewWithMaxHeight_android_maxHeight 是一个用于指定 ScrollViewWithMaxHeight 的最大高度的属性。 - Mahbubur Rahman Khan
@MahbuburRahmanKhan,请将我关于values/attrs.xml的最后一部分添加进去。 - Mario Velasco
@MahbuburRahmanKhan,请将我关于 values/attrs.xml 的最后一部分添加进去。 - undefined

0
如果你们想要制作一个非溢出的滚动视图或列表视图,只需将其放在一个RelativeLayout中,并在顶部和底部添加一个topview和bottomview即可:
<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/topview"
    android:layout_below="@+id/bottomview" >

这需要更多的信用。具体但简单的实现。 - Luke Allison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接