重叠两个Box Jetpack Compose。

12

我想在这里重叠两个 Box,或者也许更好的方法是在这种情况下使用 Row

我的设计是一个重叠的 Row 和另一个 Row,并且我已经将它包装在一个 Column 中了,这样正确吗?

这是设计,我想要的是上面的矩形与下面的矩形大小相同,并将其移动一些像素,就像您在图像中看到的那样,但它们应该具有相同的宽度但不是相同的高度。

enter image description here

如果层次结构是正确的,那还可以吗:

Column 
  Box (the one of the top)
    Row
  Box (the one of the bottom)
    Row (inside there is text and it's all the same align)

......

6个回答

12

几天前我遇到了这个问题,我使用了ConstraintLayout解决了它。

我需要做的是:

  1. build.gradle中添加implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02"
  2. 将每个Box包装在ConstraintLayout { .. }
  3. 在每个Box中添加Modifier.constrainAs以根据需要对齐Top Bottom Start End
  4. 如果您想要第一个框与第二个框具有相同的width而不是硬编码dps,则应使用width = Dimension.fillToConstraints

fillToConstraints - 布局将扩展以填充由其约束定义的空间。

没有硬编码的基本示例:

ConstraintLayout() {
            val (title, description) = createRefs()
            Box(
                modifier = Modifier
                    .padding(start = 28.dp)
                    .background(color = Red)
                    .padding(
                        horizontal = 16.dp,
                    )
                    .constrainAs(title) {
                        top.linkTo(parent.top)
                        start.linkTo(parent.start)
                        end.linkTo(parent.end)
                        width = Dimension.fillToConstraints
                    }
            ) {
                Text(text = "Hello World")
            }

            Box(
                modifier = Modifier
                    .padding(end = 4.dp)
                    .background(Color.Magenta)
                    .padding(bottom = 5.dp, start = 8.dp, end = 16.dp, top = 4.dp)
                    .constrainAs(description) {
                        top.linkTo(title.top, margin = 16.dp)
                        start.linkTo(parent.start)
                        end.linkTo(parent.end)
                        bottom.linkTo(parent.bottom)
                    }
            ) {
                Text(text = "Skizo-ozᴉʞS rules")
            }
        }

现在,您需要根据您的用户界面调整 padding,并进行适应,结果如下:

enter image description here


12

使用BoxWithConstraints而不是使用固定的宽度和高度的方式:

BoxWithConstraints(
    Modifier
        .background(color = Color.Blue)
        .padding(20.dp)) {

    val boxWidth = this.maxWidth
    Box(
        modifier = Modifier
            .width(boxWidth - 10.dp)
            .background(Color.Red)
    ) {
        Text(text = "Hello Android")
    }
    Column() {
        Spacer(modifier = Modifier
            .height(10.dp)
            .width(10.dp))
        Row( ) {
            Spacer(modifier = Modifier.width(10.dp))
            Box(
                modifier = Modifier
                    .width(boxWidth)
                    .zIndex(2f)
                    .background(Color.Yellow)
            ) {
                Text("aa", modifier = Modifier.background(color = Color.Green))
            }
        }
    }
}

two boxes same width


但是我希望顶部的那个与底部的那个具有相同的宽度。 - StuartDTO
@dmastra,你能帮我解决这个问题吗?https://stackoverflow.com/questions/71502444/compose-two-composables-overlaped-and-constraint-with-them - Skizo-ozᴉʞS ツ
嘿,谢谢你的代码帮助我实现了视图。 - Reshma

9
为了让 Composables 重叠,您应该将它们放入同一个 Box 中。尝试一下这个:
Box(modifier = Modifier.size(width = 300.dp, height = 100.dp)) {
    Row(modifier = Modifier
        .size(width = 200.dp, height = 50.dp)
        .background(color = Color.Blue)
        .align(Alignment.TopEnd)) {}
    Row(modifier = Modifier
        .size(width = 200.dp, height = 70.dp)
        .background(color = Color.Red)
        .align(Alignment.BottomStart)) {}
}

是否有可能不将宽度和高度硬编码,而使用"wrap_content"来设置呢? - StuartDTO
@StuartDTO 为什么不可能呢?省略大小修饰符即可。 - daniyelp
那么如果我省略它们,它们就直接使用wrap_content吗?我的意思是,在我的“Box”内部,我有一个带有一个文本的“Row”,在另一个“Box”内部,我有一个带有多个“Text”的“Row”,所以我希望下面的那个“Box”(即具有更多“Text”的那个)与上面的那个具有相同的宽度,因为上面的“Box”只包含一个“Text”,它会更小。 - StuartDTO
@StuartDTO 你需要以某种方式确定更大的行的宽度。但是,如果省略大小修饰符,容器将围绕内容换行。 - daniyelp
我的意思是...使用约束布局来做这个很容易,在理论上,Compose比XML更容易,也许我可以在ConstraintLayout中放一个例子,这样你就可以更好地帮助我了? - StuartDTO
显示剩余2条评论

3
你可以通过多种方式实现这一目标,
@Composable
fun BoxOverBox() {
    Box(
        modifier = Modifier.fillMaxSize()
            .background(Color.White),
        contentAlignment = Alignment.Center
    ) {
        Box(
            modifier = Modifier
                .width(200.dp)
                .height(50.dp)
                .background(Color.Red)
        )
        Box(
            modifier = Modifier
                .width(200.dp)
                .height(50.dp)
                .zIndex(2f)
                .graphicsLayer {
                    translationX = -50f
                    translationY = 50f
                }
                .background(Color.Blue)
        )
    }
}

有没有可能不将宽度和高度硬编码,而是使用“wrap_content”?另外,Box中无法识别contentAlignment。 - StuartDTO
请查看我在另一个答案中发布的评论,以更好地理解它。 - StuartDTO
我不想为这个框添加200dp和高度,我想让它在宽度方面自适应内容...并且第一个框的宽度与下面的框相同,即使文本较小。 - StuartDTO
你能帮我解决这个问题吗?https://stackoverflow.com/questions/71502444/compose-two-composables-overlaped-and-constraint-with-them - Skizo-ozᴉʞS ツ

1
要使两个框或其他可组合物以这种方式重叠,您可以在RowColumn上使用spacedBy方法进行排列,并传递一个负值。这也得到了Android文档的支持。
例如:
fun OverlappingBoxesPreview() {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.padding(20.dp),
        verticalArrangement = Arrangement.spacedBy((-30).dp),
    ) {
        Box(
            modifier = Modifier
                .size(100.dp)
                .background(Color.Red),
        )

        Box(
            modifier = Modifier
                .size(80.dp)
                .background(Color.Green),
        )

    }
}

将会产生:

enter image description here


这会减小触摸目标的大小。有没有办法避免减小触摸目标的大小呢? - undefined

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接