'How to use bias in Constraint Layout Compose

How do I set the layout_constraintHorizontal_bias prop on a Composable that is in a Constraint Layout? Here is the XML code:

<TextView
    ...
    tool:layout_constraintStart_toStartOf="parent"
    tool:layout_constraintEnd_toEndOf="parent"
    tool:layout_constraintWidth_max="wrap"
    tool:layout_constraintHorizontal_bias="0"/>

Here is how my Jetpack Compose code looks right now:

ConstraintLayout(modifier = modifier.fillMaxSize()) {
    val (button1, button2) = createRefs()
    Button(
        onClick = {},
        modifier = Modifier.constrainAs(button1) {
            top.linkTo(parent.top, margin = 16.dp)
        }
    ) {
        Text(text = "Button 1")
    }

    Button(
        onClick = {},
        modifier = Modifier.constrainAs(button2) {
            top.linkTo(button1.bottom, margin = 4.dp)
            start.linkTo(button1.end, margin = 20.dp)
            end.linkTo(parent.end, margin = 20.dp)
            width = Dimension.preferredWrapContent
        }
    ) {
        Text(text = "Button 2")
    }
}

So my question is how do I set the horizontal bias of Button 2 to be 0?



Solution 1:[1]

You have to use the linkTo function of the ConstrainScope which has more parameters:

ConstraintLayout(modifier = modifier.fillMaxSize()) {
    val (button1, button2) = createRefs()
    Button(
        onClick = {},
        modifier = Modifier.constrainAs(button1) {
            top.linkTo(parent.top, margin = 16.dp)
        }
    ) {
        Text(text = "Button 1")
    }

    Button(
        onClick = {},
        modifier = Modifier.constrainAs(button2) {              
            top.linkTo(button1.bottom, margin = 4.dp)
            linkTo(button1.end, parent.end, startMargin = 20.dp, endMargin = 20.dp, bias = 0F)
            width = Dimension.preferredWrapContent
        }
    ) {
        Text(text = "Button 2")
    }
}

Solution 2:[2]

I guess that ConstraintLayout in Jetpack Compose is not on par with the xml one yet and bias is simply missing. I found a workaround though - you can create a chain and chains actually do support bias (speaking about version 1.0.0-alpha04).

For your example, something like this should do the trick:

ConstraintLayout(modifier = modifier.fillMaxSize()) {
    // ...

    createHorizontalChain(button2, chainStyle = ChainStyle.Packed(0F))
}

Solution 3:[3]

In addition to what written till now, if you need instead vertical bias, with compose you need to use a guidelines which allow specifying a fraction for it, then link your item to guideline; something like this for positioning button1 at 70% below from top :

    ConstraintLayout(modifier = modifier.fillMaxSize()) {
    val (button1, button2) = createRefs()
    val topGuideline  = createGuidelineFromTop(0.7f)

    Button(
        onClick = {},
        modifier = Modifier.constrainAs(button1) {
            top.linkTo(topGuideline.top, margin = 0.dp)
        }
    ) {
        Text(text = "Button 1")
    }

    Button(
        onClick = {},
        modifier = Modifier.constrainAs(button2) {
            top.linkTo(button1.bottom, margin = 4.dp)
            start.linkTo(button1.end, margin = 20.dp)
            end.linkTo(parent.end, margin = 20.dp)
            width = Dimension.preferredWrapContent
        }
    ) {
        Text(text = "Button 2")
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jan Bína
Solution 3 android_dev71