包含width()、height()和size()布局修饰符以及requiredWidth()、requiredHeight()和requiredSize()。这两组修饰符之间有什么区别?我应该使用普通修饰符还是必需的修饰符?
发布于 2021-01-18 17:23:08
区别在于,普通修饰符(如宽度() )考虑布局约束条件,而必需修饰符(如requiredWidth() )则忽略它们。您可以将约束看作是测量元素的最小/最大宽度/高度。要更好地理解布局修饰符和约束是如何工作的,请查看这个职位。
让我们来看一个宽度修饰符、高度和大小的例子。
@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约束。列布局不限制其子级最小宽度,因此每个子节点都得到minWidth = 0; maxWidth = 200dp约束。前两个文本使用requiredWidth()修饰符,它忽略了这个约束,因此第二个文本比父列更宽。最后一个文本宽度根据200dp约束缩减为maxWidth = 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()宽度总是与结果元素匹配。
发布于 2022-08-11 06:34:38
在jetpack中,可组合或子可组合的合成维度是使用约束设置的,约束是有界或有限的维度和标志集合。Modifier.requiredX用于强制大小,但如果约束不受父约束的限制,则很容易破坏布局。
widthIn和requiredWidthIn的不同之处在于,前者先遵守大小修饰符或最大父维,后者才能强制约束。
/**
* Create a [Constraints]. [minWidth] and [minHeight] must be positive and
* [maxWidth] and [maxHeight] must be greater than or equal to [minWidth] and [minHeight],
* respectively, or [Infinity][Constraints.Infinity].
*/
@Stable
fun Constraints(
minWidth: Int = 0,
maxWidth: Int = Constraints.Infinity,
minHeight: Int = 0,
maxHeight: Int = Constraints.Infinity
): Constraints {
require(maxWidth >= minWidth) {
"maxWidth($maxWidth) must be >= than minWidth($minWidth)"
}
require(maxHeight >= minHeight) {
"maxHeight($maxHeight) must be >= than minHeight($minHeight)"
}
require(minWidth >= 0 && minHeight >= 0) {
"minWidth($minWidth) and minHeight($minHeight) must be >= 0"
}
return Constraints.createConstraints(minWidth, maxWidth, minHeight, maxHeight)
}在测量过程中,基于Constraints,将宽度和高度分配给可组合的Placeable。
尺寸调节剂
宽度/高度()
返回固定约束或具有相同minWidth/高度和maxWidth/高度的约束。因此,子可组合性仅限于此约束
填充物宽度/高度(分数)
覆盖从父级的max约束中可用的部分空间
min.宽度/高度(最小)
将最小宽度/高度保留为此值,以便可以使用此维度度量子可组合性。子级可以低于此值或大于此值,直到最大宽度/高度。
宽度/高度(最大)
这是孩子们可以测量的最大宽度/高度。不能用尺寸大于最大宽度/高度的尺寸来测量可组合的儿童。

@Composable
private fun ConstraintsSample1() {
Text(text = "Fixed Size")
BoxWithConstraints(modifier = Modifier
.size(100.dp)
.border(3.dp, Color.Green)) {
Box(modifier = Modifier
.size(50.dp)
.background(Color.Red))
}
Spacer(modifier=Modifier.height(10.dp))
BoxWithConstraints(modifier = Modifier
.size(100.dp)
.border(3.dp, Color.Green)) {
Box(modifier = Modifier
.size(150.dp)
.background(Color.Red))
}
Text(text = "widthIn(min)")
BoxWithConstraints(modifier = Modifier
.widthIn(min = 100.dp)
.border(3.dp, Color.Green)) {
Box(modifier = Modifier
.size(50.dp)
.background(Color.Red))
}
Spacer(modifier=Modifier.height(10.dp))
BoxWithConstraints(modifier = Modifier
.widthIn(min = 100.dp)
.border(3.dp, Color.Green)) {
Box(modifier = Modifier
.size(150.dp)
.background(Color.Red))
}
Text(text = "widthIn(max)")
BoxWithConstraints(modifier = Modifier
.widthIn(max = 100.dp)
.border(3.dp, Color.Green)) {
Box(modifier = Modifier
.size(50.dp)
.background(Color.Red))
}
Spacer(modifier=Modifier.height(10.dp))
BoxWithConstraints(modifier = Modifier
.widthIn(max = 100.dp)
.border(3.dp, Color.Green)) {
Box(modifier = Modifier
.size(150.dp)
.background(Color.Red))
}
}要求宽度/高度()
将内容的宽度/高度限制在minDp和maxDp之间。如果内容选择不满足传入约束的大小,则父布局将报告约束中强制的大小,并且内容的位置将自动偏移,以便在遵守约束的假设下,以父布局分配给子布局的空间为中心。
例如,设置Modifier.size(50.dp).size(100.dp)时,如果用户requiredIn,则应用第一个大小修饰符
Modifier.size(50.dp).requiredSizeIn(100.dp) 100.dp是强制的,但布局是2维差的一半。

@Composable
private fun ConstraintsSample2() {
Column(modifier = Modifier
.fillMaxSize()
.padding(30.dp)
.border(4.dp, Color.Cyan)) {
Text(text = "Chaining size modifiers")
Box(modifier = Modifier
.size(50.dp)
.background(Color.Yellow))
Box(modifier = Modifier
.size(50.dp)
.size(100.dp)
.background(Color.Red))
Box(modifier = Modifier
.size(50.dp)
.requiredSizeIn(100.dp)
.background(Color.Green))
Text(text = "widthIn(max)")
BoxWithConstraints(
modifier = Modifier
.width(100.dp)
.border(3.dp, Color.Green)
) {
Box(
modifier = Modifier
.requiredWidthIn(min = 20.dp, max = 50.dp)
.height(50.dp)
.background(Color.Red)
)
}
Spacer(modifier = Modifier.height(10.dp))
BoxWithConstraints(
modifier = Modifier
.width(100.dp)
.border(3.dp, Color.Green)
) {
Box(
modifier = Modifier
.requiredWidthIn(min = 150.dp, max = 200.dp)
.height(50.dp)
.background(Color.Red)
)
}
}
}在下面的示例中,当TextField没有固定大小的父级时,它会增长到最大宽度。如果使用TextField ()时设置的固定大小小于Modifier.widthIn(),则将TextField设置为父级宽度,而Modifier.requiredWidthIn()跳出父级为(TextField大小-父级)/2。

@Composable
private fun TextFieldSamples() {
Column(
modifier = Modifier
.padding(20.dp).border(2.dp, Color.Cyan)
) {
var text1 by remember { mutableStateOf("") }
Column(modifier = Modifier) {
TextField(
modifier = Modifier
.border(2.dp, Color.Green)
.widthIn(56.dp),
value = text1,
onValueChange = { text1 = it }
)
TextField(
modifier = Modifier
.border(2.dp, Color.Red)
.requiredWidthIn(56.dp),
value = text1, onValueChange = { text1 = it })
}
Spacer(modifier = Modifier.height(30.dp))
var text2 by remember { mutableStateOf("") }
Column(modifier = Modifier.width(50.dp)) {
TextField(
modifier = Modifier
.border(2.dp, Color.Green)
.widthIn(56.dp),
value = text2, onValueChange = { text2 = it })
TextField(
modifier = Modifier
.border(2.dp, Color.Red)
.requiredWidthIn(56.dp),
value = text2, onValueChange = { text2 = it })
}
}
}约束条件
约束根据大小修饰符、垂直/水平滚动或父级选择限制或希望使用最小或最大维度的方式进行更改。
在我的设备宽度上的最大设备是1080 in,在下面的示例中200.in是525 in。使用verticalScroll,这就是为什么用Constraints.Infinity来测量身高的原因

@Composable
fun ConstraintsSample3() {
Column(modifier = Modifier) {
Text(text = "No Dimension Modifier")
BoxWithConstraints(modifier = Modifier.background(Brown400)) {
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val minWidth = constraints.minWidth
val maxWidth = constraints.maxWidth
val hasBoundedHeight = constraints.hasBoundedHeight
val hasFixedHeight = constraints.hasFixedHeight
val minHeight = constraints.minHeight
val maxHeight = constraints.maxHeight
Text(
"minWidth: $minWidth, maxWidth: $maxWidth\n" +
"hasBoundedWidth: $hasBoundedWidth, hasFixedWidth: $hasFixedWidth\n" +
"minHeight: $minHeight, maxHeight: $maxHeight\n" +
"hasBoundedHeight: $hasBoundedHeight, hasFixedHeight: $hasFixedHeight",
color = Color.White
)
}
Spacer(modifier = Modifier.height(10.dp))
Text(text = "FillMaxWidth and 200.dp Height")
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.background(Red400)
) {
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val minWidth = constraints.minWidth
val maxWidth = constraints.maxWidth
val hasBoundedHeight = constraints.hasBoundedHeight
val hasFixedHeight = constraints.hasFixedHeight
val minHeight = constraints.minHeight
val maxHeight = constraints.maxHeight
Text(
"minWidth: $minWidth, maxWidth: $maxWidth\n" +
"hasBoundedWidth: $hasBoundedWidth, hasFixedWidth: $hasFixedWidth\n" +
"minHeight: $minHeight, maxHeight: $maxHeight\n" +
"hasBoundedHeight: $hasBoundedHeight, hasFixedHeight: $hasFixedHeight",
color = Color.White
)
}
Spacer(modifier = Modifier.height(10.dp))
Text(text = "wrapContentSize()")
BoxWithConstraints(
modifier = Modifier
.wrapContentSize()
.background(Orange400)
) {
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val minWidth = constraints.minWidth
val maxWidth = constraints.maxWidth
val hasBoundedHeight = constraints.hasBoundedHeight
val hasFixedHeight = constraints.hasFixedHeight
val minHeight = constraints.minHeight
val maxHeight = constraints.maxHeight
Text(
"minWidth: $minWidth, maxWidth: $maxWidth\n" +
"hasBoundedWidth: $hasBoundedWidth\n" +
"hasFixedWidth: $hasFixedWidth\n" +
"minHeight: $minHeight\n" +
"maxHeight: $maxHeight\n" +
"hasBoundedHeight: $hasBoundedHeight\n" +
"hasFixedHeight: $hasFixedHeight",
color = Color.White
)
}
Spacer(modifier = Modifier.height(10.dp))
Text(text = "200.dp Width and Height")
BoxWithConstraints(
modifier = Modifier
.width(200.dp)
.height(200.dp)
.background(Green400)
) {
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val minWidth = constraints.minWidth
val maxWidth = constraints.maxWidth
val hasBoundedHeight = constraints.hasBoundedHeight
val hasFixedHeight = constraints.hasFixedHeight
val minHeight = constraints.minHeight
val maxHeight = constraints.maxHeight
Text(
"minWidth: $minWidth, maxWidth: $maxWidth\n" +
"hasBoundedWidth: $hasBoundedWidth, hasFixedWidth: $hasFixedWidth\n" +
"minHeight: $minHeight, maxHeight: $maxHeight\n" +
"hasBoundedHeight: $hasBoundedHeight, hasFixedHeight: $hasFixedHeight",
color = Color.White
)
}
}
}
@Composable
private fun BoxWithConstraintsSample4() {
Text(text = "200.dp WidthIn(min) and HeightIn(min)")
BoxWithConstraints(
modifier = Modifier
.widthIn(min = 200.dp)
.heightIn(200.dp)
.background(Blue400)
) {
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val minWidth = constraints.minWidth
val maxWidth = constraints.maxWidth
val hasBoundedHeight = constraints.hasBoundedHeight
val hasFixedHeight = constraints.hasFixedHeight
val minHeight = constraints.minHeight
val maxHeight = constraints.maxHeight
Text(
"minWidth: $minWidth, maxWidth: $maxWidth\n" +
"hasBoundedWidth: $hasBoundedWidth, hasFixedWidth: $hasFixedWidth\n" +
"minHeight: $minHeight, maxHeight: $maxHeight\n" +
"hasBoundedHeight: $hasBoundedHeight, hasFixedHeight: $hasFixedHeight",
color = Color.White
)
}
Text(text = "200.dp requiredWidth(min) and requiredHeight(min)")
BoxWithConstraints(
modifier = Modifier
.requiredWidthIn(min = 200.dp)
.requiredHeightIn(200.dp)
.background(Pink400)
) {
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val minWidth = constraints.minWidth
val maxWidth = constraints.maxWidth
val hasBoundedHeight = constraints.hasBoundedHeight
val hasFixedHeight = constraints.hasFixedHeight
val minHeight = constraints.minHeight
val maxHeight = constraints.maxHeight
Text(
"minWidth: $minWidth, maxWidth: $maxWidth\n" +
"hasBoundedWidth: $hasBoundedWidth, hasFixedWidth: $hasFixedWidth\n" +
"minHeight: $minHeight, maxHeight: $maxHeight\n" +
"hasBoundedHeight: $hasBoundedHeight, hasFixedHeight: $hasFixedHeight",
color = Color.White
)
}
Text(text = "200.dp defaultMinSize()")
BoxWithConstraints(
modifier = Modifier
.defaultMinSize(200.dp)
.background(Pink400)
) {
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val minWidth = constraints.minWidth
val maxWidth = constraints.maxWidth
val hasBoundedHeight = constraints.hasBoundedHeight
val hasFixedHeight = constraints.hasFixedHeight
val minHeight = constraints.minHeight
val maxHeight = constraints.maxHeight
Text(
"minWidth: $minWidth, maxWidth: $maxWidth\n" +
"hasBoundedWidth: $hasBoundedWidth, hasFixedWidth: $hasFixedWidth\n" +
"minHeight: $minHeight, maxHeight: $maxHeight\n" +
"hasBoundedHeight: $hasBoundedHeight, hasFixedHeight: $hasFixedHeight",
color = Color.White
)
}
Text(text = "200.dp WidthIn(max)")
BoxWithConstraints(
modifier = Modifier
.widthIn(max = 200.dp)
.background(Purple400)
) {
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val minWidth = constraints.minWidth
val maxWidth = constraints.maxWidth
val hasBoundedHeight = constraints.hasBoundedHeight
val hasFixedHeight = constraints.hasFixedHeight
val minHeight = constraints.minHeight
val maxHeight = constraints.maxHeight
Text(
"minWidth: $minWidth, maxWidth: $maxWidth\n" +
"hasBoundedWidth: $hasBoundedWidth, hasFixedWidth: $hasFixedWidth\n" +
"minHeight: $minHeight, maxHeight: $maxHeight\n" +
"hasBoundedHeight: $hasBoundedHeight, hasFixedHeight: $hasFixedHeight",
color = Color.White
)
}
}https://stackoverflow.com/questions/65779226
复制相似问题