英文:
Compose layout child outside parent bounds while maintaining height
问题
我试图使子Box
在其高度较大且以某种方式对齐时扩展到父Box
之外,因为子框底部对齐,所以我希望在父框内时不可见Cyan线。
但实际上会发生这种情况。
子框高度调整并打印为大约20.dp。
是否有可以利用以实现此效果的Modifier
?
val density = LocalDensity.current
Box(modifier = Modifier
.padding(top = 250.dp)
.fillMaxWidth()
.height(20.dp)
.background(Color.Red)
.clipToBounds()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(80.dp)
.background(Color.Green)
.align(Alignment.BottomCenter)
.onSizeChanged {
density.run {
Log.i("Box Height", it.height.toDp().toString())
}
}
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Cyan)
.align(Alignment.TopCenter)
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Yellow)
.align(Alignment.BottomCenter)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Magenta)
.align(Alignment.CenterStart)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Blue)
.align(Alignment.CenterEnd)
)
}
}
英文:
I'm trying to get a child Box
to extend outside parent Box
when it's height is greater and it's aligned in a certain way. Because the child box is aligned bottom, I'd expect the Cyan line to not be visible when inside the parent box
But instead this happens
Child Box height resizes and prints out as being roughly 20.dp.
Is there a Modifier
I can leverage to achieve this effect?
val density = LocalDensity.current
Box(modifier = Modifier
.padding(top = 250.dp)
.fillMaxWidth()
.height(20.dp)
.background(Color.Red)
.clipToBounds()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(80.dp)
.background(Color.Green)
.align(Alignment.BottomCenter)
.onSizeChanged {
density.run {
Log.i("Box Height", it.height.toDp().toString())
}
}
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Cyan)
.align(Alignment.TopCenter)
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Yellow)
.align(Alignment.BottomCenter)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Magenta)
.align(Alignment.CenterStart)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Blue)
.align(Alignment.CenterEnd)
)
}
}
答案1
得分: 1
在Jetpack Compose中,您无法通过增加内容大小来增加父级大小。使用默认的Composables,甚至无法测量超出父级最小-最大宽度/高度约束范围之外的内容内的Composables。
Modifier.height(20.dp)
返回 minHeight =20.dp,max=20.dp,因此父级始终以20.dp高度测量。
但是,Modifier.wrapContentX(unbounded, align)
或 Modifier.requiredX()
修饰符可以更改内容的 Constraints
最小-最大范围。
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(unbounded = true, align = Alignment.Bottom)
.height(80.dp)
.background(Color.Green)
将允许带有绿色背景的Box以80.dp进行测量,并通过底部对齐可以获得预期的结果。
wrapContent的定义如下:
允许内容以其所需的高度进行测量,而不考虑传入的测量最小高度约束,如果unbounded为true,也不考虑传入的测量最大高度约束。如果内容的测量大小小于最小高度约束,则将其与该最小高度空间对齐。如果内容的测量大小大于最大高度约束(仅在unbounded为true时可能),则在最大高度空间上对齐。
我用带有Constraints的Box替换了带有绿色背景的Box,这样您可以查看其中的Constraints,如果替换父级,您还可以查看来自父级的Constraints。
在上面的代码中,BoxWithConstraints
是一个用于显示Constraints的Composable,它会打印出红色Box和绿色Box的最小高度和最大高度。
此外,您的代码中包含了一个 @Preview
和 @Composable
的示例函数 Test()
,该函数在一个Column中包含了上述的BoxWithConstraints和其他Composables。
希望这有助于您理解Jetpack Compose中的布局和Constraints。
英文:
In Jetpack Compose you cannot increase parent size by increasing content size.
With default Composables it's not even possible to measure Composables inside content out of range of min-max width/height of Constraints from parent.
Modifier.height(20.dp)
returns minHeight =20.dp, max=20.dp so parent is always measured with 20.dp height.
However Modifier.wrapContentX(unBounded, align)
or Modifier.requiredX()
modifiers can change Constraints
min-max range for content.
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(unbounded = true, align = Alignment.Bottom)
.height(80.dp)
.background(Color.Green)
will let Box with green background to be measured with 80.dp and by aligning bottom you will be able get expected result.
wrapContent definition is as
> Allow the content to measure at its desired height without regard for
> the incoming measurement minimum height constraint, and, if unbounded
> is true, also without regard for the incoming measurement maximum
> height constraint. If the content's measured size is smaller than the
> minimum height constraint, align it within that minimum height space.
> If the content's measured size is larger than the maximum height
> constraint (only possible when unbounded is true), align over the
> maximum height space.
I replaced Box with green background with BoxWithConstraints so you can check out Constraints inside it, if you replace parent you can also constraints coming from it too.
@Preview
@Composable
fun Test() {
Column(Modifier.fillMaxSize()) {
BoxWithConstraints(
modifier = Modifier
.padding(top = 250.dp)
.fillMaxWidth()
.height(20.dp)
.background(Color.Red)
.clipToBounds()
) {
println("Red Box minHeight: $minHeight, maxHeight: $maxHeight")
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(unbounded = true, align = Alignment.Bottom)
.height(80.dp)
.background(Color.Green)
) {
println("Green Box minHeight: $minHeight, maxHeight: $maxHeight")
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Cyan)
.align(Alignment.TopCenter)
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Yellow)
.align(Alignment.BottomCenter)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Magenta)
.align(Alignment.CenterStart)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Blue)
.align(Alignment.CenterEnd)
)
}
}
}
}
答案2
得分: 1
我找到了一个将 requiredHeight
与 offset
y 结合的解决方案。我认为它也需要偏移量,因为在添加了 requiredHeight
后,Modifier.align(Alignment.BottomCenter)
会失效。
val parentHeight = 20.dp
val childHeight = 80.dp
val offsetY = (parentHeight - childHeight) / 2
Box(modifier = Modifier
.padding(top = 250.dp)
.fillMaxWidth()
.height(parentHeight)
.background(Color.Red)
.clipToBounds()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.requiredHeight(childHeight)
.offset(y = offsetY)
.background(Color.Green)
.align(Alignment.BottomCenter)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Cyan)
.align(Alignment.TopCenter)
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Yellow)
.align(Alignment.BottomCenter)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Magenta)
.align(Alignment.CenterStart)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Blue)
.align(Alignment.CenterEnd)
)
}
}
英文:
I found a solution combining requiredHeight
with offset
y. It needs the offset too I think because Modifier.align(Alignment.BottomCenter)
breaks after requiredHeight
is added.
val parentHeight = 20.dp
val childHeight = 80.dp
val offsetY = (parentHeight - childHeight) / 2
Box(modifier = Modifier
.padding(top = 250.dp)
.fillMaxWidth()
.height(parentHeight)
.background(Color.Red)
.clipToBounds()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.requiredHeight(childHeight)
.offset(y = offsetY)
.background(Color.Green)
.align(Alignment.BottomCenter)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Cyan)
.align(Alignment.TopCenter)
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
.background(Color.Yellow)
.align(Alignment.BottomCenter)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Magenta)
.align(Alignment.CenterStart)
)
Box(
modifier = Modifier
.fillMaxHeight()
.width(5.dp)
.background(Color.Blue)
.align(Alignment.CenterEnd)
)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论