ericn
ericn

Reputation: 13103

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

Upvotes: 7

Views: 5748

Answers (3)

Maxim Petlyuk
Maxim Petlyuk

Reputation: 1174

Essentially, the issue is that chains are removing all margins.
There is another way if you still want to add margin for chain elements:

createVerticalChain(
  image, 
  title.withChainParams(topMargin = 12.dp), 
  text, 
  chainStyle = ChainStyle.Packed(0.5f)
)

Upvotes: 0

AnonyKnow
AnonyKnow

Reputation: 287

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.

Upvotes: 7

Phil Dukhov
Phil Dukhov

Reputation: 87794

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())
}

Upvotes: 1

Related Questions