Skip to content

Introduction to ConstraintLayout in Compose

Oscar Adame Vazquez edited this page Jan 14, 2022 · 3 revisions

There are 3 ways to create constraints in ConstraintLayout:

  • Imbedded in Modifier
  • ConstraintSet Composable
  • JSON ConstraintSet

More on the Modifier & ConstraintSet Syntax.

More on the JSON ConstraintSet Syntax.

Imbedded in Modifier

@Preview
@Composable
public fun ScreenExample() {
    ConstraintLayout(
        modifier = Modifier.fillMaxSize()
    ) {
        val (button, title) = createRefs()               // define some ids
        val g1 = createGuidelineFromStart(80.dp)         // define a Guideline "g1"

        Button(
            modifier = Modifier.constrainAs(button) {   // Define Constraints for "button"
                top.linkTo(title.bottom, 16.dp)         // Constrain top to bottom of title with 16dp margin
                start.linkTo(g1)                        // Constrain start to guideline (0dp margin implied)
            },
            onClick = {},
        ) {
            Text(text = stringResource(id = R.string.log_in))
        }
        Text(modifier = Modifier.constrainAs(title) {  // Define Constraints for "title"
            centerVerticallyTo(parent)                 // center vertically in parent (equivalent to top_toTop="parent" bottom_toBottom="parent"
            start.linkTo(g1)                           // Constrain start to guideline 
        },
            text = stringResource(id = R.string.welcome_header),
            style = MaterialTheme.typography.h2,
        )
    }
}

ConstraintSet

@Preview
@Composable
public fun ScreenExample2() {
    ConstraintLayout(
        ConstraintSet {                                  // Create a constraint set which is passed to ConstraintLayout
            val button = createRefFor("button")          // Create ID "button" 
            val title = createRefFor("title")            // Create ID "title" 
            val g1 = createGuidelineFromStart(80.dp)     // Create Guideline "g1"
            constrain(button) {                          // Create Constraint for id "button" 
                top.linkTo(title.bottom, 16.dp)          // Constrain top to bottom of title with 16dp margin
                start.linkTo(g1)                         // Constrain start to g1 (0dp margin implied)
            }
            constrain(title) {                           // Create Constraint for id "title" 
                centerVerticallyTo(parent)               // center vertically in parent (equivalent to top_toTop="parent" bottom_toBottom="parent"
                start.linkTo(g1)                         // Constrain start to guideline 
            }
        },
        modifier = Modifier
            .fillMaxSize()
    ) {
        Button(
            modifier = Modifier.layoutId("button"),      // Button has an id "button"
            onClick = {},
        ) {
            Text(text = stringResource(id = R.string.log_in))
        }
        Text(modifier = Modifier.layoutId("title"),       // Texthas an id "title"
            text = stringResource(id = R.string.welcome_header),
            style = MaterialTheme.typography.h2,
        )
    }
}

Vertical Anchors (v_anchor)

  • top.linkTo(v_anchor, margin)
  • bottom.linkTo(v_anchor, margin)
  • baseline.linkTo(v_anchor, margin)

Horizontal Anchors (h_anchor)

  • start.linkTo(h_anchor, margin)
  • end.linkTo(h_anchor, margin)

Miscellaneous

  • centerVerticallyTo(widget_id)
  • centerHorizontallyTo(widget_id)
  • centerAround(v_anchor)
  • circular(widget_id , angle , distance )
  • linkTo(v_anchor, v_anchor, margin_top , margin_end, bias)
  • linkTo(h_anchor, h_anchor, margin_start , margin_end, bias)

JSON ConstraintSet

@Preview(group = "new")
@Composable
public fun ScreenExample3() {
    ConstraintLayout(
        ConstraintSet("""                                // Constraint set initialized with a json string
            {
                Header: { exportAs: 'example 3'},       // header sectioned used in debugging 
                g1: { type: 'vGuideline', start: 80 },  // Create Guideline g1
                button: {                               // Create Constraints for id "button"
                  top: ['title', 'bottom', 16],         // Constrain top to bottom of title with 16dp margin
                  start: ['g1', 'start']                // Constrain start to g1 (0dp margin implied)
                },
                title: {                                // Create Constraints for id "button"
                  centerVertically: 'parent',           // center vertically in parent (equivalent to top_toTop="parent" bottom_toBottom="parent"
                  start: ['g1', 'start']                // Constrain start to guideline 
                }
            }
        """),
        modifier = Modifier.fillMaxSize()
    ) {
        Button(
            modifier = Modifier.layoutId("button"),     // define id of Button to "button"
            onClick = {},
        ) {
            Text(text = stringResource(id = R.string.log_in))
        }
        Text(modifier = Modifier.layoutId("title"),     // define id of of Text to "title"
            text = stringResource(id = R.string.welcome_header),
            style = MaterialTheme.typography.h2,
        )
    }
}