Skip to main content

Nested MotionLayout Tutorial

Nested MotionLayout Tutorial

MotionLayout is a library that allows you to “describe any transitions in XML, no matter how complex,” and this is true to an extent. If you have ever worked with MotionLayout, you probably know that this declarative ability only applies to direct children.

If you’re reading this blog, it probably means you are in search of a simple way to use MotionLayout with nested children, which is what you usually find in a beautifully developed app. If this is the case, you are in luck. In this nested MotionLayout tutorial, I am going to show you how to use MotionLayout with nested children using only a few lines of code in just five steps. 

1. Create one MotionLayout per level inside your XML like in the following example:

MotionLayout per level inside your XML

As you can see, there are three MotionLayout with their corresponding scenes: activity_main_scene, header_contain_scene, and child_header_container_scene. Each one of the previous scenes will have the responsibility of animating its direct children, so you’ll want to move all necessary constraintSet and constraint in order to achieve this.

 

2. Make the activity_main_scene the conductor of this orchestra 

Implement MotionLayout.TransitionListener in your Activity, Fragment, or independent dedicated class like this:

class MainActivity : AppCompatActivity(), MotionLayout.TransitionListener {

3. Set up the transaction listener for each one (call this fun in onCreate, onViewCreated, or something like that): 

private fun setUpMotionLayoutListener() = with(binding) {
   rootContainer.setTransitionListener(this@MainActivity)
   headerContainer.setTransitionListener(this@MainActivity)
   childHeaderContainer.setTransitionListener(this@MainActivity)
}

4. Synchronize them using the following code:

private fun updateNestedMotionLayout(motionLayout: MotionLayout?) = motionLayout?.let {
   with(binding) {
       if (it.id == rootContainer.id) {
           headerContainer.progress = it.progress
           childHeaderContainer.progress = it.progress
       }
   }
}

That’s all! It’s really that simple. Now that you know how to use MotionLayout with nested children, give it a try in your own app. You can check out a fully functional example of using MotionLayout for nested children at GitHub Nested MotionLayout

MotionLayout with nested children final result

References:

Android Developer Training 

Miguel Hincapie GitHub

 

New call-to-action