Animation / Scene / Transition / Translate

Curved Motion – Part 1

The Material design guidelines advocate the use of authentic motion and the Play Store app has (at the time of writing) recently had an update to provide curved motion when transitioning from a list into a detail view. In this short series we’ll look at how to implement curved motion.

The Material design guidelines suggest:

Not all objects move the same way. Lighter or smaller objects may move faster because they require less force, and larger or heavier objects may need more time to speed up.

Use curved motion and avoid linear spatial paths. Identify the qualities of motion best suited to your object, and represent their motion accordingly. Curves represent that change over time, for a particular value range. Find a curve that fits that character of motion you are describing.

If we look at the current version of the Play Store app we can see that this is applied when the images follow a curved path as we transition to and from the detail view rather than simply following a straight path:

For anyone lucky enough to be able to specify minSdkVersion="21" this is really easy because the Transitions framework does a lot of the hard work for you. We’ve covered Transitions before on Styling Android so we won’t do a deep dive on how these work – we’ll focus on how to use curved motion within these transitions.

Let’s take a look at this by first declaring a couple of layouts to represent our two scenes for our transitions:

These are identical with the exception that the inner View is positions differently within the parent. This will simulate the different positions of the View so that we can create translation animations using the Transitions framework.

Next we’ll take a look at our Activity:

There’s nothing special going on here. I’ve elected to encapsulate all of the Transitions logic in to an external class to make it easier to swap in separate implementations later on. We initialise this by providing a Context, the container for the scenes, the layout ids of both scenes, and a Transition id which is actually the key bit – we’ll cover this once we’ve got the basic behaviour wired up.

Once again, there’s nothing special going on here. In newInstance() we inflate our two scenes from the supplied layout ids, and wire them up to a TransitionManager. EnterAction hooks up an OnClickListener when each scene is entered to add the necessary click behaviour to toggle between the two scenes.

If we were to use this with a standard ChangeBounds Transition is would cause the cause the View to move between the two positions represented by the two scenes in a straight line. However, if we run this we can see that we actually get a curved path:

The reason for this is because of the transition id that we passed in to newInstance() which was inflated in to a Transition object. So let’s take a look at it:

So this is a ChangeBounds transition, but it has an ArcMotion child which is what does all the hard work for us. It will calculate an appropriate arc between the start and end points but the attributes will case the arc to flatten to a straight line if the line between the start and end points is too close to either a horizontal or vertical line.

So, where you’re already using Transitions it is incredibly easy to change you transitions from straight lines to curves just by customising your Transition definitions slightly.

However, not many of us are able to use this, so in the next article we’ll look it to a simple technique for applying this to standard property Animators which will work back to API 11.

The source code for this article is available here.

© 2015, Mark Allison. All rights reserved.

CC BY-NC-SA 4.0 Curved Motion – Part 1 by Styling Android is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at http://blog.stylingandroid.com/license-information.

Leave a Reply

Your email address will not be published. Required fields are marked *