android Jetpack合成中的修饰符fillMaxWidth()和wrapContentWidth()

3duebb1j  于 2023-01-15  发布在  Android
关注(0)|答案(2)|浏览(191)

我对Jetpack Compose中的修饰符fillMaxWidth()和wrapContentWidth()的作用感到困惑。我已经通读了文档并查看了它们的实现,但我仍然不确定它们是如何工作的(内部)。
以下是我对他们工作的理解:

  • fillMaxWidth()将元素的宽度设置为其父容器的最大宽度,我的理解是,它通过将最小宽度和最大宽度设置为等于父容器的最大宽度来实现这一点。
  • wrapContentWidth()使布局元素与元素内容一样宽。

我的问题是:
1.对于fillMaxWidth(),我对它内部功能的理解是否正确(将最小宽度和最大宽度设置为等于父对象的最大宽度)?
1.在wrapContentWidth()的情况下,是否通过将元素的最小和最大宽度设置为内容的宽度,使布局元素与元素的内容一样宽?
1.另外,如果我将下面的修饰符应用到一个元素上,它到底会做什么?**modifier = Modifier. fillMaxWidth(). wrapContentWidth()wrapContentWidth()不会只是撤销fillMaxWidth所做的事情吗?如果我改变顺序,使用modifier = Modifier. wrapContentWidth(). fillMaxWidth()**呢?
谢谢你的帮助。

jobtbby3

jobtbby31#

  • fillMaxWidth()会将组合的最小和最大宽度设置为容器允许的最大值,以填充所有空间
  • wrapContentWidth()会将最小宽度设置为0(因此忽略之前的最小宽度),如果将unbounded设置为true,则可以对最大宽度执行相同的操作

您可以将它们组合起来以获得一些效果,例如,您可以使用fillMaxWidth设置特定的背景色,然后使用wrapContentWidthwrapContentHeight在同一容器中居中组合一个子容器,如下图所示(我使用了wrapContentSize,但同样的方法也适用于wrapContentWidthwrapContentHeight

@Preview(widthDp = 360, heightDp = 360)
@Composable
private fun PreviewMOdifier() {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.Red)
            .wrapContentSize(Alignment.Center)
            .background(Color.Blue)
    ) {
        Text(
            text = "This is the body",
            modifier = Modifier
                .padding(all = 16.dp)
                .background(Color.Yellow)
        )
    }
}

编辑:这里是另一个例子,尝试删除Box修改器中的wrapContentHeight,以便查看预览如何变化

@Preview(heightDp = 360)
@Composable
private fun PreviewThreeBlock() {
    PlaygroundTheme {
        Surface(
            color = MaterialTheme.colorScheme.background
        ) {
            Box(
                modifier = Modifier.wrapContentHeight().background(Color.Red)
            ) {
                Text(text = "FooBar")
            }
        }
    }
}
ryevplcw

ryevplcw2#

在Jetpack合成中,使用来自大小修改器的Constraints设置子对象或/和容器合成对象的大小,父对象或滚动返回Constraints. Infinity。
度量具有父约束或修改的约束的可组合对象将确定子可组合对象的大小
您可以查看this answer的“约束”部分。
Modifier.fillmaxWidth(fraction)将Constraints的最小和最大宽度设置为相等,因此当您调用measurable.measure(constraints)时,您的子Composable将使用此固定值进行测量。
当你的父可组合对象是行、列或其他内置可组合对象时,wrapWidth()实际上在大多数情况下是不需要的,因为当你不给你的可组合对象分配大小修饰符时,它是用父对象的最小-最大约束范围来度量的,该范围介于0和父对象宽度之间。
然而,Box具有称为propagateMinConstraintsSurface的参数,其是Box,其中propagateMinConstraints = true强制最小值Constraints为直接后代,如本答案中所解释的或如@Francesc所解释的。

@Composable
private fun WrapWidthExample() {
    Row() {
        Surface(
            modifier = Modifier
                .size(200.dp)
                .border(2.dp, Color.Yellow),
            onClick = {}) {
            Column(
                modifier = Modifier
                    .size(50.dp)
                    .background(Color.Red, RoundedCornerShape(6.dp))
            ) {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Green, RoundedCornerShape(6.dp))
                )

            }
        }
        Surface(
            modifier = Modifier
                .size(200.dp)
                .border(2.dp, Color.Yellow),
            onClick = {}) {
            Column(
                modifier = Modifier
                    .wrapContentWidth()
                    .background(Color.Red, RoundedCornerShape(6.dp))
            ) {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Green, RoundedCornerShape(6.dp))
                )

            }
        }
    }
}

如果没有Modifier.wrapContentWidth(),200.dp(我的设备中为525 px)将被强制为红色列以测量Measurable,但如果有wrapContentWidth,则允许可组合组件使用其自己的最小约束,该约束为0,因为未分配任何修饰符。

  • 允许内容以其所需宽度进行测量,而不考虑传入测量 * [最小宽度约束][Constraints.minWidth],如果[unbounded]为true,则也不考虑 * 传入测量[最大宽度约束][Constraints.maxWidth]。如果 * 内容的测量大小小于最小宽度约束,[align] * 它在最小宽度空间内。如果内容的测量大小大于最大 * 宽度约束(仅当[unbounded]为true时才可能),[align]在最大 * 宽度空间上对齐。

从这个修饰符返回的约束是

val wrappedConstraints = Constraints(
        minWidth = if (direction != Direction.Vertical) 0 else constraints.minWidth,
        minHeight = if (direction != Direction.Horizontal) 0 else constraints.minHeight,
        maxWidth = if (direction != Direction.Vertical && unbounded) {
            Constraints.Infinity
        } else {
            constraints.maxWidth
        },
        maxHeight = if (direction != Direction.Horizontal && unbounded) {
            Constraints.Infinity
        } else {
            constraints.maxHeight
        }
    )

基本上,wrapContentX可以在父对象强制子合成对象使用其约束时使用,这可以在构建自定义布局(例如)或如上所述使用曲面时完成。
1.在Jetpack合成中,除非你链接Modifier.requiredX,否则应用第一个大小修饰符,而忽略后面的一个,除非它们之间没有填充、大小等。你可以查看第一个链接中的requiredSize答案以了解更多细节。

相关问题