Android Jetpack Compose 宽度/高度/大小修饰符与 requiredWidth / requiredHeight / requiredSize

Android Jetpack Compose width / height / size modifier vs requiredWidth / requiredHeight / requiredSize

Android Jetpack Compose 包含 width(), height() and size() layout modifiers as well as requiredWidth(), requiredHeight() and requiredSize()。这两组修饰符有什么区别?我应该使用 plain 修饰符还是 required 修饰符?

区别在于 plain 修饰符,如 width() take into account layout Constraints while required modifiers like requiredWidth() ignore them. You can think of constrains as min/max width/height of a measured element. To better understand how layout modifiers and constraints work take a look at .

让我们看一个 width 修饰符的例子,heightsize 的行为方式相同.

@Composable
fun WidthModifierExample() {
    val columnWidth = 200.dp

    Column(
        modifier = Modifier
            .width(columnWidth)
            .border(1.dp, Color.Gray)
    ) {
        Text(
            text = "requiredWidth = parent - 50",
            modifier = Modifier
                .requiredWidth(columnWidth - 50.dp)
                .background(Color.LightGray)
        )
        Text(
            text = "requiredWidth = parent + 50",
            modifier = Modifier
                .requiredWidth(columnWidth + 50.dp)
                .background(Color.LightGray)
        )
        Text(
            text = "width = parent - 50",
            modifier = Modifier
                .width(columnWidth - 50.dp)
                .background(Color.LightGray),
        )
        Text(
            text = "width = parent + 50",
            modifier = Modifier
                .width(columnWidth + 50.dp)
                .background(Color.LightGray)
        )
    }
}

深灰色边框为列边界,文本背景为浅灰色。 Modifier.width(200.dp) 应用于列,因此它接收 minWidth = 200dp; maxWidth = 200dp 约束。 Column 布局不限制其子项的最小宽度,因此每个子项都受到 minWidth = 0; maxWidth = 200dp 约束。前两个文本使用忽略此约束的 requiredWidth() 修饰符,因此第二个文本比父列宽。根据 maxWidth = 200dp 约束,最后一个文本宽度减小为 200dp,因为它使用了 width() 修饰符。

在上面的示例中,仅限制了文本的最大宽度。让我们看另一个同样限制最小宽度的例子:

@Composable
fun WidthModifierExample() {
    Column(
        modifier = Modifier.border(1.dp, Color.Gray)
    ) {
        val minWidth = 140
        val maxWidth = 200
        val widthDescriptions = arrayOf(
            WidthDescription(minWidth - 50, "min - 50"),
            WidthDescription((minWidth + maxWidth) / 2, "between min and max"),
            WidthDescription(maxWidth + 50, "max + 50")
        )

        for (widthDescription in widthDescriptions) {
            Text(
                text = "requiredWidth = ${widthDescription.description}",
                modifier = Modifier
                    .border(.5.dp, Color.Red)
                    .widthIn(minWidth.dp, maxWidth.dp)
                    .background(Color.LightGray)
                    .requiredWidth(widthDescription.width.dp)
            )
        }

        for (widthDescription in widthDescriptions) {
            Text(
                text = "width = ${widthDescription.description}",
                modifier = Modifier
                    .border(.5.dp, Color.Red)
                    .widthIn(minWidth.dp, maxWidth.dp)
                    .background(Color.LightGray)
                    .width(widthDescription.width.dp)
            )
        }
    }
}

data class WidthDescription(
    val width: Int,
    val description: String
)

在这种情况下,Column() 不添加任何约束,但每个子项 Text() 都包含在 widthIn() 修饰符中,后者添加了自己的约束。浅灰色背景显示文本大小,而红色边框显示结果元素的尺寸。如您所见,前三个文本的 requiredWidth() 修饰符忽略了外部约束,结果元素宽度及其子 Text() 宽度可能不同。最后三个文本使用 width() 修饰符,它考虑了约束,因此 Text() 宽度始终与结果元素匹配。