Categories
android ui

Android ConstraintLayout 2.0: ConstraintLayoutStates

With the introduction of ConstraintLayout 2.0, there is an interesting new feature called ConstraintLayoutStates. ConstraintLayoutStates allow you to create a layout with different states and switch between them easily. Typically, most layouts contain a loading state, initial state, end state and error state. Using ConstraintLayoutStates, there is a clean way to switch between these different states.

How do you use this new feature? Glad you asked!

Step 1: Create your different states in separate XML files

Create the different state layout files that your layout needs. Each layout must include the same views, they can just have different properties such as their visibility, or their constraints.

ConstraintLayoutStates example layouts
3 layouts for the different layout states.

Step 2: Create a ConstraintLayoutStates XML file

In the xml resource folder, create an xml file containing your states. In this example, we will call it constraint_layout_states_example.xml. Inside this file place all the different representations of your layout. Give them meaningful ids such as startloading etc. and then link them to the relevant constraint files.

<?xml version="1.0" encoding="utf-8"?>
<ConstraintLayoutStates xmlns:android="http://schemas.android.com/apk/res/android"
                        xmlns:app="http://schemas.android.com/apk/res-auto">
    <State
            android:id="@+id/start"
            app:constraints="@layout/activity_cl_states_start"/>
    <State
            android:id="@+id/loading"
            app:constraints="@layout/activity_cl_states_loading"/>
    <State
            android:id="@+id/end"
            app:constraints="@layout/activity_cl_states_end"/>
</ConstraintLayoutStates>

 

Step 3: Switch between the states

In your activity/fragment, you can now easily switch between these states based on different conditions. You will first need to load the state description using loadLayoutDescription() on your ConstraintLayout object. Once you have done that, you can call constraintLayout.setState() with any of the states that you have defined in the previous states file.

In the example below, we are setting the state to the loading state. Then after some time (in this example I am just posting a delayed runnable, but this could easily be a network call that returns at a later stage), we are setting it to the end state.

class ConstraintLayoutStatesExampleActivity : AppCompatActivity() {

    val handler = Handler()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_cl_states_start)
        stateConstraintLayout.loadLayoutDescription(R.xml.constraint_layout_states_example)
        var changed = false
        buttonBakeCake.setOnClickListener {
            stateConstraintLayout.setState(R.id.loading, 0, 0)
            postDelayed(handler,  {
                stateConstraintLayout.setState(if (changed) R.id.start else R.id.end,0, 0)
                changed = !changed
            }, null, 3000L)
        }
    }
}

The above example running on a device:ConstraintLayoutStates example

That’s it! You should now be able to use ConstraintLayoutStates in your own apps. This example can be found on Github here.

Enjoyed this post? Let me know your thoughts on Twitter!