Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compose ConstraintLayout margin not working

enter image description here There seems to be no margin whatsoever even though I explicitly set the margin between the image and title to be 12dp

What am I missing?

Setting the heights to Dimension.value(0dp) did not do the trick btw

My view component:

@Preview
@Composable
fun GenericEmptyState() {
    MaterialTheme() {
        ConstraintLayout(
            Modifier
                .fillMaxSize(1f)
                .background(Color.White)
                .padding(24.dp)
        ) {
            val (image, title, text, cta) = createRefs()

            Image(
                painterResource(R.drawable.hearts),
                contentDescription = "hearts",
                modifier = Modifier.constrainAs(image) {
                    top.linkTo(parent.top)
                    start.linkTo(parent.start)
                    end.linkTo(parent.end)
                    height = Dimension.value(150.dp)
                    width = Dimension.value(150.dp)
                }
            )

            Text(
                "this is the title",
                Modifier.constrainAs(title) {
                    top.linkTo(image.bottom, 12.dp)
                    start.linkTo(parent.start)
                    end.linkTo(parent.end)
                    height = Dimension.wrapContent
                })

            Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat",
                Modifier.constrainAs(text) {
                    top.linkTo(title.bottom, 12.dp)
                    start.linkTo(parent.start)
                    end.linkTo(parent.end)
                }
            )

            createVerticalChain(image, title, text, chainStyle = ChainStyle.Packed(0.5f))
        }
    }
}

Compose version 1.0.5

like image 324
ericn Avatar asked Jul 31 '26 23:07

ericn


2 Answers

I've had a similar case. If anyone do the following, can solve the problem

...
Text(
    "this is the title",
    Modifier
        // First, set padding above constrainAs
        .padding(top = 12.dp)
        .constrainAs(title) {
            // Remove margin value
            top.linkTo(image.bottom)
            start.linkTo(parent.start)
            end.linkTo(parent.end)
            height = Dimension.wrapContent
        })

Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat",
    Modifier
        // set padding top too
        .padding(top = 12.dp)
        .constrainAs(text) {
            // Remove margin value
            top.linkTo(title.bottom)
            start.linkTo(parent.start)
            end.linkTo(parent.end)
        })
...

Since Modifier processes layout sequentially, so if padding is set first, the calculated size is used.

like image 105
AnonyKnow Avatar answered Aug 03 '26 21:08

AnonyKnow


You're not using createVerticalChain as intended. I haven't found this function description in Compose documentation - seems it's still under development, but androidx.constraintlayout.widget documentation (on which Compose ConstraintLayout should be based) contains the following description:

This operation sets all the related margins to 0.

Removing this line solves your problem.


Also Here's how you can build the same layout without ConstraintLayout:

  1. Use Column to place items.
  2. Space items by 12.dp using arrangement
  3. Center items using alignment
Column(
    verticalArrangement = Arrangement.spacedBy(12.dp),
    horizontalAlignment = Alignment.CenterHorizontally,
    modifier = Modifier
        .fillMaxSize(1f)
        .background(Color.White)
        .padding(24.dp)
) {
    Image(
        painterResource(R.drawable.my_image_2),
        contentDescription = "hearts",
        modifier = Modifier
            .size(150.dp)
    )

    Text("this is the title")

    Text(LoremIpsum(30).values.first())
}
like image 35
Philip Dukhov Avatar answered Aug 03 '26 20:08

Philip Dukhov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!