我正在寻找一种使布局元素(行或列)的子元素在垂直方向上延伸超出其父元素边界的方法。我想这样做是因为我想让背景中的行设置颜色,但子元素的周围区域是透明的。
这是我想要实现的目标的视觉表示:(想发布图像,但我还没有足够的声誉)
-------
| | <- extended element
| |
--| |----------
| | | | <- row with background
| ------- |
-------------------
理想情况下,该行的假设父级应该尊重扩展子级的高度。这是因为,据我了解,扩展部分通常会被其上方的其他组件或屏幕边缘切断(因为它超出了边界)。
我已经尝试了两件事
使用此方法,可能可以通过某种方式实现,但我没有找到使用 LayoutCooperatives lambda 参数提供的位置方法来实现此目的的方法。
此外,我观察到子元素在第一次合成后“跳跃”位置。如果可能的话我想避免这种情况。
有了这个,我可以更改子元素的位置以及行本身,但调整大小似乎不起作用。
也许我在某个地方做错了什么,但这就是我现在得到的:
val itemWidth = 128
val itemHeight = 256
Row(
modifier = Modifier.fillMaxWidth()
) {
Box(
modifier = Modifier
.width(itemWidth.dp)
.layout { measurable, constraints ->
val placeable = measurable.measure(
constraints.copy(
maxHeight = itemHeight.dp.roundToPx()
)
)
layout(
placeable.width,
placeable.height
) {
placeable.place(0, 0)
}
}
.background(color = Color.Blue)
)
Text(
text = "This is text filling the rest of the row",
modifier = Modifier
.weight(1f)
.padding(8.dp)
)
}
}
约束是衡量可组合项作为可测量项的范围。如果未设置 minHieght,则它来自父级或先前的大小约束。如果它是 0,您的可组合项将在 256.dp 的 0 像素值之间进行测量,因此您需要将 minHeight 设置为与 maxHeight 相同的值。
同时设置 placeable.place(0, yPos) 和 yPos 低于 0 将使其位于 Row 中定义的位置之上。
最后,如果您不将高度分配给父行,它将获得具有最大高度的子行的高度,其中
Box
带有布局修饰符。
val itemWidth = 128
val itemHeight = 256
@Preview
@Composable
fun LayoutTest() {
Column(
modifier = Modifier.fillMaxSize()
) {
Row(
modifier = Modifier
.padding(top = 300.dp)
.fillMaxWidth()
.height(50.dp)
.border(2.dp, Color.Red)
) {
Box(
modifier = Modifier
.width(itemWidth.dp)
.layout { measurable, constraints ->
val placeable = measurable.measure(
constraints.copy(
minHeight = itemHeight.dp.roundToPx(),
maxHeight = itemHeight.dp.roundToPx()
)
)
layout(
placeable.width,
placeable.height
) {
placeable.placeRelative(0, 0)
}
}
.background(color = Color.Blue)
.border(2.dp, Color.Green)
)
Text(
text = "This is text filling the rest of the row",
modifier = Modifier
.weight(1f)
.padding(8.dp)
)
}
}
}
结果是这样的
蓝色框居中的原因是它不遵守父级约束,因为父级试图将其居中。您可以参考这个答案了解更多详细信息,但一般来说,如果测量不遵守父级或之前的修饰符约束,则无论它更大还是更小,它都是中心。
为了克服这个问题,你需要用
抵消两个差值val userOffset = 0
placeable.placeRelative(
x = 0,
y = (constraints.maxHeight - placeable.height) / 2 + userOffset
)
将会有结果
如果为 userOffset 设置负值,蓝色框将放置在靠近顶部的位置。