Introduction to MotionLayout (part II)

Nicolas Roard
Jun 27, 2018 · 5 min read

This is part II of a series of articles introducing MotionLayout. If you haven’t yet, please check part I !

In this article, we will continue covering basic MotionLayout features through various examples, introducing custom attribute interpolation, image operations and keyframes.


Example 03 : Custom attribute

In part I we last created a MotionLayout with a self-contained MotionScene. We can take advantage of this to specify transition on attributes that are not related to the position only.

Image for post
Image for post

Indeed, originally ConstraintSet only encapsulated the layout rules; but for richer animations, we often need to transition other things (for example, a background color). In ConstraintLayout 2.0, ConstraintSet can also store custom attribute states. Let’s say we want the following motion, where our view’s background will change color:

Image for post
Image for post

Previously, you would have had to handle this in code. Now, you can instead specify the attribute directly in XML:

<Constraint
android:id="@+id/button" ...>
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#D81B60"/>
</Constraint>

Here’s the modified MotionScene file for the above animation:

CustomAttribute are specified with the attributeName, which needs to match the getter/setter methods of an object such that:

  • getter: getName (e.g. getBackgroundColor)

The value type also needs to be specified:

  • customColorValue

Lastly, when defining a custom attribute, you do need to define it both in the start and the end ConstraintSet.


Example 04 : ImageFilterView (1/2)

When dealing with complex transitions, there’s often the need to do some operations on images, and animating them. ConstraintLayout 2.0 brings a small utility class called ImageFilterView (which is a subclass to AppCompatImageView) to easily allow this.

Let’s do for example a simple cross-fade between two images, such as:

Image for post
Image for post

We first need to create a MotionLayout file with the image:

The main difference from a normal ImageView here is the altSrc attribute:

<android.support.constraint.image.ImageFilterView
android:id="@+id/image"
...
android:src="@drawable/roard"
app:altSrc="@drawable/hoford"/>

The MotionScene file will simply apply a custom attribute on the crossfade property:


Example 05 : ImageFilterView (2/2)

ImageFilterView offers more capabilities:

saturation : 0 = grayscale, 1 = original, 2 = hyper saturated

contrast : 1 = unchanged, 0 = gray, 2 = high contrast

warmth : 1 = neutral, 2 = warm (red tint), 0.5 = cold (blue tint)

crossfade (with app:altSrc)

Here’s another example showing how to play with an image saturation:

Image for post
Image for post

Specifying the saturation can be done simply by using a custom attribute:

<CustomAttribute
motion:attributeName="saturation"
motion:customFloatValue="1" />

Here’s the MotionLayout file we use in this example:

And here’s the corresponding scene file:


Keyframes

The general idea for MotionLayout is that “resting states” are implemented as ConstraintSets. This way, we know that the resulting layouts will correctly adapt to different screen sizes: essentially, MotionLayout will behave like a typical ConstraintLayout.

In some situations, you may want to have an intermediate state — a state to go through, but not a state to stay in. You could specify more than two ConstraintSets, but a more lightweight approach is to use Keyframes.

Keyframes can be applied to position or to attribute values; they basically let you specify a change at a point in time during the transition.

For example, you may want to say that at 25% of the transition, the widget should turn red. Or that at 50% of the transition, the widget should move up.


Example 06 : Keyframe (1/2), position

There are several ways (pathRelative, deltaRelative, parentRelative) you can set up a position keyframe (KeyPosition), which we will cover in detail in part IV of this series.

Image for post
Image for post

As a quick introduction to position keyframes, here’s how you would specify an intermediate position happening at 50% of the total transition, positioned 25% of the screen:

<Transition ...>
<KeyFrameSet>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.25"
motion:framePosition="50"
motion:target="@+id/button"/>
</KeyFrameSet>
</Transition>

The resulting motion will be:

Image for post
Image for post

As usual, the MotionLayout file itself is pretty simple:

The MotionScene file is very similar to the previous ones we already saw, with the addition to a KeyPosition element:


Example 07 : Keyframe (2/2), attribute

In a similar manner to position keyframes, you can specify an attribute value at a specific point in the transition (using KeyAttribute).

Image for post
Image for post

For example, we may want to specify the scale and rotation of the object we are manipulating at the same 50% position to get the following transition:

Image for post
Image for post

This can be achieved by adding a KeyAttribute element in the KeyFrameSet:

<KeyFrameSet>
<KeyAttribute
android:scaleX="2"
android:scaleY="2"
android:rotation="-45"
motion:framePosition="50"
motion:target="@id/button" />
</KeyFrameSet>

The MotionLayout file is the same as in the previous example, and the only difference in the MotionScene file is adding the KeyAttribute:


Conclusion

This second article covers more advanced functionalities of MotionLayout, giving examples of how to take advantage of custom attributes and keyframes to create more compelling animations.

You can find the source code for those examples in the ConstraintLayout examples github repository.

There’s a lot more covered in this series of articles:

  • Introduction to MotionLayout (part I)

Feedback, feature request, bug reports? please file them on the android issue tracker.

More info on ConstraintLayout & MotionLayout ? Follow us on twitter, @camaelon and @johnhoford

Google Developers

Engineering and technology articles for developers, written…

Thanks to Sean McQuillan

Nicolas Roard

Written by

I’m working on Android stuff at Google

Google Developers

Engineering and technology articles for developers, written and curated by Googlers. The views expressed are those of the authors and don't necessarily reflect those of Google.

Nicolas Roard

Written by

I’m working on Android stuff at Google

Google Developers

Engineering and technology articles for developers, written and curated by Googlers. The views expressed are those of the authors and don't necessarily reflect those of Google.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store