Android Compose 约束布局问题

6

Compose 版本:1.0.0-beta04

ConstraintLayout Compose 版本:1.0.0-alpha05

Composable:

@Composable
fun comp1() {
    Surface(Modifier
        .fillMaxWidth()
        .height(50.dp), color = Color.Red) {

        ConstraintLayout(Modifier.fillMaxSize()) {
            val guide_line = createGuidelineFromAbsoluteRight(.2f)
            val (icon_ref, box_ref, spacer_ref) = createRefs()
            
            Icon(Icons.Filled.Search, null,
                modifier = Modifier.constrainAs(icon_ref) {
                    absoluteLeft.linkTo(guide_line)
                    absoluteRight.linkTo(parent.absoluteRight)
                    top.linkTo(parent.top)
                    bottom.linkTo(parent.bottom)
                }
            ) 

            Box(Modifier
                .background(Color.Blue)
                .fillMaxSize()
                .constrainAs(box_ref) {
                    absoluteLeft.linkTo(parent.absoluteLeft)
                    absoluteRight.linkTo(guide_line)
                    top.linkTo(parent.top)
                    bottom.linkTo(parent.bottom)
                }) {}

            Spacer(Modifier
                .background(Color.Yellow)
                .width(2.dp)
                .fillMaxHeight()
                .constrainAs(spacer_ref) {
                    absoluteRight.linkTo(guide_line)
                })
        }
    }

}

预览:

输入图像描述

输入图像描述

正如您所看到的,这些项目没有被限制在一个预期的范围内。 视图通过基于 ConstraintLayout 的约束来绘制,除非约束出现了问题或者是有意为之,否则不会超出屏幕。

1个回答

16

Box 组合中删除 fillMaxSize() 修饰符,并应用约束条件 width = Dimension.fillToConstraints

类似这样:

Surface(Modifier
    .fillMaxWidth()
    .height(50.dp), color = Color.Red) {

    ConstraintLayout(Modifier.fillMaxSize()) {
        val guide_line = createGuidelineFromAbsoluteRight(.2f)
        val (icon_ref, box_ref, spacer_ref) = createRefs()

        Icon(Icons.Filled.Search, null,
            modifier = Modifier.constrainAs(icon_ref) {
                start.linkTo(guide_line)
                end.linkTo(parent.end)
                top.linkTo(parent.top)
                bottom.linkTo(parent.bottom)
            }
        )

        Box(contentAlignment=Alignment.CenterStart,
            modifier = Modifier
            .background(Color.Blue)
            .fillMaxHeight()
            .constrainAs(box_ref) {
                start.linkTo(parent.start)
                end.linkTo(guide_line)
                top.linkTo(parent.top)
                bottom.linkTo(parent.bottom)
                width = Dimension.fillToConstraints //ADD THIS
            }) {

            Text(text = "Text ", color = Yellow)
        }

        Spacer(Modifier
            .background(Color.Yellow)
            .width(2.dp)
            .fillMaxHeight()
            .constrainAs(spacer_ref) {
                end.linkTo(guide_line)
            })
    }
}

输入图像描述


不幸的是,这并没有解决问题。使用您的答案,Box将会超出屏幕范围。尝试在盒子的内容中添加一个Text,并设置Alignment.CenterStart属性,您会发现文本的开头被截断了。 - yazan sayed
1
@yazansayed 你是对的。问题在于在“Box”中使用了修饰符fillMaxSize()而不是约束width = Dimension.fillToConstraints。回答已更新。 - Gabriele Mariotti
1
非常感谢,我想这应该是包含在ConstraintLayout中的任何可组合对象的默认宽度和高度。如果可以,请也帮忙看一下这个问题:https://stackoverflow.com/questions/67159235/android-compose-can-composables-store-more-than-a-single-state - yazan sayed
1
非常感谢!这让我疯狂了一整天。在 ConstraintLayout 中的 Box 很难调试,直到我看到了你关于 width = Dimension.fillToConstraints 的评论。 - Utkarsh Tiwari

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