为什么修饰符大小没有被覆盖?
Why are the modifier sizes not overwritten?
我有一个可组合函数,它可以为表面指定大小。
@Composable
private fun CreateImage(modifier: Modifier = Modifier) {
Surface(
modifier = modifier
.size(150.dp)
.padding(5.dp),
shape = CircleShape,
border = BorderStroke(1.dp, Color.LightGray)
) {
Image(
painter = painterResource(id = R.drawable.profile_image),
contentDescription = "Profile Image",
contentScale = ContentScale.Crop
)
}
}
当我调用另一个方法并更改修饰符参数中的大小时,它不应该坚持 150dp。
如果我调用这个方法:
@Composable
private fun ChangeSize(name: String) {
CreateImage(Modifier.size(100.dp))
}
即使在 CreateImage 中我将其设置为 150dp,它仍保持 100dp 的大小。为什么大小不更改为 150dp 并保持 100dp?
我认为应该将其更改为 150dp。为什么不是这样?
可组合项的大小始终为 150.dp 的原因在于修饰符的应用方式。当修饰符链接到可组合项时,它们会从上到下按顺序应用,直到应用最后一个修饰符。这可以用一个非常简单的 Box
可组合
来证明
@Composable
fun Screen(){
Box(
modifier = Modifier
.size(100.dp)
.background(color = Color.Yellow)
.background(color = Color.Green)
.background(color = Color.Red)
)
在这个简单的 Box
可组合项中,渲染颜色将为 Color.Red
,因为它将是在绘制到屏幕上之前应用的最后一种颜色。
您上面的示例中也发生了类似的事情。即使您使用修饰符 100.dp 调用可组合项,应用的最终大小也是 150.dp,因为带有 100.dp 的修饰符在修饰符链中应用得太早了。
用这个替换您的可组合项,它应该会按预期工作
@Composable
private fun CreateImage(modifier: Modifier = Modifier) {
Surface(
modifier = Modifier
.size(150.dp)
.padding(5.dp)
.then(modifier), //this last modifier will override everything above
shape = CircleShape,
border = BorderStroke(1.dp, Color.LightGray)
) {
Image(
painter = painterResource(id = R.drawable.profile_image),
contentDescription = "Profile Image",
contentScale = ContentScale.Crop
)
}
}
修饰符使用它获得的第一个大小,当人们不为您的可组合项提供任何大小时,这是一个很棒的功能。
例如
CircleDisplay(
modifier = circleModifier
.widthIn(min = 70.dp)
.heightIn(min = 70.dp),
color = color
)
如果有人不提供任何宽度或高度的任何修改器,而不是高度和宽度为 0,则您为您的可组合项提供最小尺寸。您可以根据您的实施将其更改为最大或精确大小。但是当用户修饰符有一些宽度高度而不是你的时,由于使用了第一个尺寸,所以使用了他们提供的宽度高度。
Slider 等默认可组合项也使用此模式,因此在不设置任何尺寸的情况下,它具有 48.dp 高度并填充其父项的最大宽度。
Slider 下的 BoxWithConstraint 为
BoxWithConstraints(
modifier
.minimumTouchTargetSize()
.requiredSizeIn(minWidth = ThumbRadius * 2, minHeight = ThumbRadius * 2)
.sliderSemantics(value, tickFractions, enabled, onValueChange, valueRange, steps)
.focusable(enabled, interactionSource)
) {
// Rest of the Slider Implementation
}
我有一个可组合函数,它可以为表面指定大小。
@Composable
private fun CreateImage(modifier: Modifier = Modifier) {
Surface(
modifier = modifier
.size(150.dp)
.padding(5.dp),
shape = CircleShape,
border = BorderStroke(1.dp, Color.LightGray)
) {
Image(
painter = painterResource(id = R.drawable.profile_image),
contentDescription = "Profile Image",
contentScale = ContentScale.Crop
)
}
}
当我调用另一个方法并更改修饰符参数中的大小时,它不应该坚持 150dp。
如果我调用这个方法:
@Composable
private fun ChangeSize(name: String) {
CreateImage(Modifier.size(100.dp))
}
即使在 CreateImage 中我将其设置为 150dp,它仍保持 100dp 的大小。为什么大小不更改为 150dp 并保持 100dp?
我认为应该将其更改为 150dp。为什么不是这样?
可组合项的大小始终为 150.dp 的原因在于修饰符的应用方式。当修饰符链接到可组合项时,它们会从上到下按顺序应用,直到应用最后一个修饰符。这可以用一个非常简单的 Box
可组合
@Composable
fun Screen(){
Box(
modifier = Modifier
.size(100.dp)
.background(color = Color.Yellow)
.background(color = Color.Green)
.background(color = Color.Red)
)
在这个简单的 Box
可组合项中,渲染颜色将为 Color.Red
,因为它将是在绘制到屏幕上之前应用的最后一种颜色。
您上面的示例中也发生了类似的事情。即使您使用修饰符 100.dp 调用可组合项,应用的最终大小也是 150.dp,因为带有 100.dp 的修饰符在修饰符链中应用得太早了。
用这个替换您的可组合项,它应该会按预期工作
@Composable
private fun CreateImage(modifier: Modifier = Modifier) {
Surface(
modifier = Modifier
.size(150.dp)
.padding(5.dp)
.then(modifier), //this last modifier will override everything above
shape = CircleShape,
border = BorderStroke(1.dp, Color.LightGray)
) {
Image(
painter = painterResource(id = R.drawable.profile_image),
contentDescription = "Profile Image",
contentScale = ContentScale.Crop
)
}
}
修饰符使用它获得的第一个大小,当人们不为您的可组合项提供任何大小时,这是一个很棒的功能。
例如
CircleDisplay(
modifier = circleModifier
.widthIn(min = 70.dp)
.heightIn(min = 70.dp),
color = color
)
如果有人不提供任何宽度或高度的任何修改器,而不是高度和宽度为 0,则您为您的可组合项提供最小尺寸。您可以根据您的实施将其更改为最大或精确大小。但是当用户修饰符有一些宽度高度而不是你的时,由于使用了第一个尺寸,所以使用了他们提供的宽度高度。
Slider 等默认可组合项也使用此模式,因此在不设置任何尺寸的情况下,它具有 48.dp 高度并填充其父项的最大宽度。
Slider 下的 BoxWithConstraint 为
BoxWithConstraints(
modifier
.minimumTouchTargetSize()
.requiredSizeIn(minWidth = ThumbRadius * 2, minHeight = ThumbRadius * 2)
.sliderSemantics(value, tickFractions, enabled, onValueChange, valueRange, steps)
.focusable(enabled, interactionSource)
) {
// Rest of the Slider Implementation
}