Ladies and gentlemen, if you have not checked out ConstraintLayout 2.0, you are missing out. I have been playing around with it and I’m at the point of no return. Ever wanted to make cool animations? Well, it’s a walk in the park. You just need to know where the park is and how big it is. ?
About ConstraintLayout
ConstraintLayout 2.0 was announced at Google I/O 2018. What got me excited was MotionLayout, a tool for layout animations. Yes, you read that right. Layout Animations. In this series well take a look at how we can use motion layout to create a Twitter Profile like UI.
Yap… All this done using XML. ?I’d recommend that you check out this introduction by Nicolas Roard.
Intro
Here’s a break down:
- Adding ConstraintLayout 2.0 & MotionLayout
- Motion Layout
- MotionScene
- OnSwipe
- Transition
- ConstraintSets
- KeyFrames
- Conclusion
Adding MotionLayout
To add motion layout to your project, simply add the following to your gradle file:
MotionLayout
As the name says, it’s Motion + Layout files. Motion layout builds upon ConstraintLayout. It allows us to handle layout transitions and complex motion. Think of it this way, ConstraintLayout allows us to create complex layouts and MotionLayout is the icing on the cake adding animations to the layout.
Voila . ..
Something to take note of, MotionLayout is a subclass of ConstraintLayout. So we need to make sure our root tag is MotionLayout.
MotionScene
We’ll a separate XML file inside
res/xml
that will contain MotionLayout information then we will reference the file in out activity file like so.
app:layoutDescription="@xml/scene_twitter_profile"
The MotionScene contains the animation magic.
Transition
We’ll start by checking out the Transition Element. This defines what the start and end states are. We define the states using the respective attributes:
constraintSetEnd
and
constraintSetStart
. The ids of the states can be anything,thesame way we name views.
OnSwipe
OnSwipe is contained inside the Transition definition. It lets you manage the transition by matching the motion of the users finger. There are 3 main params:
-
dragDirection:
Think of this as the scroll direction (top / bottom / left / right
). -
touchAnchorId:
This is the view we are tracking, in our case it will be the RecylerView. When the user scrolls up or down (dragDirection ) do some magic -
touchAnchorSide:
the side of the object that should track your finger (right /left /bottom /top
)
This is how it looks
We are almost there… Stay with me. ?
ConstraintSet
We will use ConstraintSets to handle our states. To do so, we will create two ConstraintSets or should I say we’ll create a set. ?No? Fine…
We can now add constraints for the views in the layout file. You will notice that it looks like a normal file just that we don’t specify the widget.
With only those lines of code, we get the following effect. We are not there yet but this is progress. We need to fix a couple of things but before we do that, let’s see what’s happening.
There are a 3 things to take note of:
- Attributes Override: Defined attributes in the scene file will override those in the layout file. ( layout_height, padding, margin, constraints …) So you can actually get rid of them in the layout file making it cleaner. I really like this.
- ConstraintSet values: If you take a closer look at the layout height, you’ll see there’s a difference. The first one defines the size of the image in its original state (expanded) and the second one in its final state (collapsed). This gives us a collapsing bar effect.
- CustomAttributes: We have access to various attributes that allow us to modify a widget. In this tutorial, we are using imageAlpha to modify the transparency of the image. You can read more about CustomAttributes here.
Image Fix
When we scroll up, we want the image to scroll under the toolbar. To do this we simply change the elevation of the toolbar in the final state (collapsed). We update it from 2dp to 4dp. JUST that and ….
KeyFrameSet
Before we wrap this up, I’ll touch on KeyFrameSets. They let us change a widget at a certain point during the transition. In our case, we want to shrink the profile image when scrolling up and down.
The KeyFrameSet contains KeyAttribute. We framePosition to specify when we want to modify the image. It takes in a value between 0-100. In our case, when we are 20% into the transition, start
Final Result
After patching it all up, we get this:
Conclusion
You can see how MotionLayout is amazing and powerful. No Java/Kolin code was used. Let that sink in.
It goes to show the power of MotionLayout. I’m really looking forward to the UI editor and other amazing updates.
The source code for this article is available on Github
Resources
- Build a Responsive UI with ConstraintLayout
- Android Fundaments: ConstraintLayout by Rebecca Franks
- ConstraintLayout CodeLab
The source code for this article is available on Github