Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.

Compose ConstraintLayout DSL Syntax

Oscar Adame Vazquez edited this page Jan 19, 2022 · 8 revisions

A quick reference on how to implement some typical ConstraintLayout cases in Compose.

ConstraintSet DSL vs Modifier DSL

Both syntax work very much alike with a slight difference in setup.

ConstraintSet

    val constraintSet = ConstraintSet {
        val titleText = createRefFor("title")
        // Helpers are defined in this scope
        createStartBarrier(titleText)

        constrain(titleText) {
            // constraints, dimensions, transforms
        }
    }
    ConstraintLayout(constraintSet) {
        Text(text = "", modifier = Modifier.layoutId("title"))
    }

Modifier

    ConstraintLayout {
        val title = createRef()
        // Helpers are defined in this scope
        createStartBarrier(title)

        Text(text = "", modifier = Modifier.constrainAs(title) {
            // constraints, dimensions, transforms
        })
    }
  • Note that only the immediate children Composables can be constrained
  • Prefer ConstraintSet for more manageable and reusable Layouts

ConstrainScope

The available API under the ConstrainScope, ie:

constraint(createRefFor("id")) {
    // The API here
}

Constraints

Constrain a Composable to another using Anchorable.linkTo()

constrain(title) {
   start.linkTo(parent.start, margin = 10.dp)
}

Or align a Composable with center...()

constrain(title) {
   centerTo(parent)                          // Center around or inside the given reference
   centerHorizontallyTo(parent, bias = 0.5f) // Constrain start & end to the same anchors at the given reference
   centerVerticallyTo(parent, bias = 0.5f)   // Constrain top & bottom to the same anchors at the given reference
}

Dimension Behavior

Use androidx.constraintlayout.compose.Dimension to define the dimension behavior of a Composable.

constrain(title) {
   width = Dimension.value(10.dp)
}

The typical use-cases:

  • Dimension.value(Dp)
  • Dimension.wrapContent
  • Dimension.matchParent
  • Dimension.fillToConstraints - Equivalent to "match_constraints" in the View system

See the Dimension interface documentation for more.

Ratio

You can use Dimension.ratio(String) to define a dimension as a proportion to the other.

Where the String is a Width:Height ratio.

   height = Dimension.value(10.dp)
   width = Dimension.ratio("4:1")    // The width will be 40dp
// ---------
   width = Dimension.wrapContent
   height = Dimension.ratio("1:0.25")   // The height will be a fourth of the resulting wrapContent width

Visibility

As with the View system, you can set the visibility of a Composable.

  • Visibility.Visible - The default Visibility of Composables in ConstraintLayout
  • Visibility.Invisible - Effectively the same as setting the alpha to 0.0f
  • Visibility.Gone - The dimensions of the Composable will collapse to 0, and constraints will still be considered

Composables constrained to another with visibility Gone will use goneMargin instead:

constrain(title) {
   visibility = Visibility.Gone
}
constrain(name) {
   start.linkTo(title.end, margin = 4.dp, goneMargin = 8.dp)  // The margin in the layout will be 8dp
}

Helpers

Chains

Create horizontal and vertical chains by passing the ConstrainedLayoutReferences of each Composable that should be in the chain. The order each reference is passed will be reflected in the chain.

   // text1 is the head (left-most element) of the chain
   createHorizontalChain(text1, text2, button1, ChainStyle.Packed)

Additionally, chains can be constrained on their axis to reposition them (by default, they are constrained to the parent). Do not try to re-define the constraints for the elements in the chain, it will result in unexpected behavior.

   // text1 start is constrained to parent.start, button1 end is constrained to parent.end
   val chain1 = createHorizontalChain(text1, button1)

   constrain(chain1) {
      // text1 start will now be constrained to vGuideline1
      start.linkTo(vGuideline1)

      // button1 end will now be constrained to vGuideline2
      end.linkTo(vGuideline2)
   }

Guidelines

Barriers

Clone this wiki locally