Search code examples
android-jetpack-composeandroid-constraintlayout

goneMargin in ConstraintLayout with Compose


I'm trying to use ConstraintLayout in Compose. I want the second Composable to be constrained at the end of the first Composable. The first composable can exist or not. In each case, I would like to have different margins. Thus, I use goneMargin but this seems to not be respected. Do I need to do something else?

ConstraintLayout {
    val (firstItemRef, secondItemRef) = createRefs()

    if (isFirstItemVisible) {
        Text(
            text = "First",
            modifier = Modifier.constrainAs(firstItemRef) {
                top.linkTo(anchor = parent.top)
                start.linkTo(anchor = parent.start)
            }
        )
    }

    Text(
        text = "Second",
        modifier = Modifier.constrainAs(secondItemRef) {
            top.linkTo(anchor = parent.top)
            start.linkTo(anchor = firstItemRef.end, margin = 8.dp, goneMargin = 16.dp)
        }
    )
}

As a workaround, we could do something like that, but this seems to counterfeit the purpose of goneMargin

Text(
    text = "Second",
    modifier = Modifier.constrainAs(secondItemRef) {
        val margin = if (isFirstItemVisible) 8.dp else 16.dp
        val end = if (isFirstItemVisible) firstItemRef.end else parent.end
        top.linkTo(anchor = parent.top)
        start.linkTo(anchor = end, margin = margin)
    }
)

Solution

  • You have to use the visibility property in ConstrainScope like this:

    ConstraintLayout(Modifier.fillMaxSize()) {
        val (firstItemRef, secondItemRef) = createRefs()
        Text(
            text = "First",
            modifier = Modifier.constrainAs(firstItemRef) {
                top.linkTo(anchor = parent.top)
                start.linkTo(anchor = parent.start)
                // >> This is what you want <<<
                visibility = if (isFirstItemVisible) Visibility.Visible else Visibility.Gone
            }
        )
        Text(
            text = "Second",
            modifier = Modifier.constrainAs(secondItemRef) {
                top.linkTo(anchor = parent.top)
                start.linkTo(anchor = firstItemRef.end, margin = 8.dp, goneMargin = 16.dp)
            }
        )
    }