区别在于像width() 这样的plain 修饰符会考虑布局Constraints 而像requiredWidth() 这样的必需 修饰符会忽略它们。您可以将约束视为测量元素的最小/最大宽度/高度。要更好地了解布局修改器和约束的工作原理,请查看 this post。
让我们看一个 width 修饰符的例子,height 和 size 的行为方式相同。
@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() 宽度始终与结果元素匹配。