Posts Tagged

code

Magic With MotionLayout

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.

Twitter Profile Ui build with motion layout
MotionLayout in action

 

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.

Fast forward creating the layout….

Voila ...

ConstraintLayout

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:

  1. 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.
  2. 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.
  3. 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 to scale down the image. 

Still on KeyFrames, we want the UserName and tweet count to appear on the toolbar. We’ll update the alpha value of the TextViews to “1” when we are 100% into the transition. This will make them visible since we’ve set the widgets to invisible by default.

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

  1. Build a Responsive UI with ConstraintLayout
  2. Android Fundaments: ConstraintLayout by Rebecca Franks
  3. ConstraintLayout CodeLab

The source code for this article is available on Github