Introduction to ConstraintSet

Tan Jun Rong avatar
Tan Jun Rong

Constraint Layout

ConstraintLayout has been around for a while now. There are a couple of ways to define constraints for ConstraintLayout:

So far I've been only using xml, but sometimes it is needed to define the constraints dynamically. In this post, I want to discuss how to define constraints for ConstraintLayout using ConstraintSet 👇

Spec

Let's start out with a spec. Pretend that we want to build this, placing a red row under a page:

Row at the Bottom
Row at the Bottom

Using xml

To achieve this with ConstraintLayout using xml,

The xml version looks like this:

activity_main.xml

<android.support.constraint.ConstraintLayout ... android:layout_width="match_parent" android:layout_height="match_parent"> <TextView ... android:layout_width="0dp" android:layout_height="wrap_content" android:text="Hello World" android:textSize="20dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> android.support.constraint.ConstraintLayout>

The interesting part that makes the TextView sticks to the bottom of the screen and becomes as wide as the width of the screen is this 3 lines:

...
    <TextView
        ...
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
...

They align the row's edges to the parents's.

Re-writing using ConstraintSet

Let's implement the same thing using ConstraintSet.

We will begin with an empty layout like below, let's called it empty_main.xml.

empty_main.xml

<ConstraintLayout android:id="@+id/constraintLayout" android:layout_width="match_parent" android:layout_height="match_parent"> ConstraintLayout>

The TextView will be in a separte file called text_view_row.xml:

text_view_row.xml

xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textViewRow" android:layout_width="0dp" android:layout_height="wrap_content" android:background="@color/md_red_300" android:padding="30dp" android:text="Hello World" android:textColor="@color/md_white_1000" android:textSize="20dp" />

Now that we have 1 empty container constraintLayout, and a TextView in another file, we can use ConstraintSet to hook them up and reproduce the same result.

This is the code to use ConstraintSet:

fun onCreate() {    
    setContentView(R.layout.empty_main)

    // 1. Inflate the TextView row & add the the TextView
    val textViewRow = LayoutInflater.from(this).inflate(R.layout.text_view_row, constraintLayout, false)
    constraintLayout.addView(textViewRow)
    
    // 2. Clone the constraints into ConstraintSet
    val set = ConstraintSet()
    set.clone(constraintLayout)
    
    // 3. Connect TextView row with ConstraintLayout
    set.connect(textViewRow.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
    set.connect(textViewRow.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START)
    set.connect(textViewRow.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
    
    // 4. applying the constraint
    set.applyTo(constraintLayout)
}

Following the code, I can roughly divide them into 4 steps, I will add some explanations to each steps:

  1. Inflate the TextView row

    • (self-explanatory)
  2. Clone the constraints into ConstraintSet

    • if we create a new ConstraintSet, it will be empty, so we need to clone the constraints from the constraintLayout object
  3. Connect TextView row with ConstraintLayout

    • now we have a copy of ConstraintSet of constraintLayout, we can connect it with textViewRow
    • set.connect(textViewRow.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM) is similar to be using app:layout_constraintBottom_toBottomOf="parent" in xml
  4. Applying the Constraint

    • finally, we apply the ConstraintSet to constraintLayout.

After this, we will get this again.

Row at the Bottom with ConstraintSet
Row at the Bottom with ConstraintSet

This is a short post and that's it!

The code is available in this Github Repo, ConstraintSetStudy.