为什么修改器大小没有被覆盖



我有一个可组合的函数,它为曲面指定大小。

@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。为什么不是这样?

Modifier使用它得到的第一个大小,当人们不向您的Composable提供任何大小时,这是一个很好的功能。

例如

CircleDisplay(
modifier = circleModifier
.widthIn(min = 70.dp)
.heightIn(min = 70.dp),
color = color
)

如果有人没有提供任何具有任何宽度或高度的修改器,而不是具有0的高度和宽度,则为您的可组合对象指定最小大小。您可以根据您的实现将其更改为最大或精确大小。但当用户修改器有一些宽度-高度而不是您的宽度-高度时,由于使用了第一个大小,他们提供的那个就被使用了。

Slider等默认组件也使用此模式,因此在不设置任何尺寸的情况下,它的高度为48.dp,填充其父对象的最大宽度。

滑块下的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
}

可组合文件的大小始终为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的修饰符调用你的compositable,get应用的最终大小是150.dp,因为你用100.dp-get的修饰符在修饰符链中应用得太早了。

用这个替换你的堆肥,它应该像预期的一样工作

@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
)
}
}

最新更新