Advertisement
  1. Code
  2. Android SDK
Code

Adding Physics-Based Animations to Android Apps

by
Difficulty:BeginnerLength:MediumLanguages:

Animations that feel fluid and realistic tend to make user interfaces more attractive. No wonder Material Design places so much emphasis on them! 

If you've ever tried creating such animations, however, you know that the simple animators and interpolators offered by the Android SDK are often not good enough. That's why recent revisions of the Android Support Library come with a physics module called Dynamic Animation.

With Dynamic Animation, you can create physics-based animations that closely resemble the movements of objects in the real world. You can also make them respond to user actions in real time. In this tutorial, I'll show you how to create a few such animations.

Prerequisites

To follow along, make sure you have the following:

1. Adding Dependencies

To be able to use Dynamic Animation in your project, you must add it as an implementation dependency in your app module's build.gradle file:

In this tutorial, we're going to be animating an ImageView widget. It will, of course, have to display some images, so open the Vector Assets Studio and add the following Material icons to your project:

  • sentiment neutral
  • sentiment very satisfied

Here's what they look like:

Two Material icons

For best results, I suggest you set the size of the icons to 56 x 56 dp.

2. Creating a Fling Animation

When you fling an object in the real world, you give it a large momentum. Because momentum is nothing but the product of mass and velocity, the object will initially have a high velocity. Gradually, however, thanks to friction, it slows down until it stops moving completely. Using Dynamic Animation's FlingAnimation class, you can simulate this behavior inside your app.

For the sake of demonstration, let us now create a layout containing a flingable ImageView widget, displaying the ic_sentiment_neutral_black_56dp icon, and a Button widget users can press to trigger the fling animation. If you place them both inside a RelativeLayout widget, your layout XML file will look like this:

In the above code, you can see that the Button widget has an onClick attribute. By clicking on the red light-bulb icon Android Studio shows beside it, you can generate an associated on-click event handler inside your Activity class:

You can now create a new instance of the FlingAnimation class using its constructor, which expects a View object and the name of an animatable property. Dynamic Animation supports several animatable properties, such as scale, translation, rotation, and alpha.

The following code shows you how to create a FlingAnimation instance that can animate the X-coordinate of our layout's ImageView:

By default, a FlingAnimation instance is configured to use 0 pixels/second as its initial velocity. That means the animation would stop as soon as it's started. To simulate a realistic fling, you must always remember to call the setStartVelocity() method and pass a large value to it.

Additionally, you must understand that without friction, the animation will not stop. Therefore, you must also call the setFriction() method and pass a small number to it.

The following code configures the FlingAnimation instance such that the ImageView is not flung out of the bounds of the user's screen:

At this point, you can simply call the start() method to start the animation.

If you run the app now and press the button, you should be able to see the fling animation.

 

It is worth noting that you don't specify a duration or an end value when creating a physics-based animation—the animation stops automatically when it realizes that its target object is not showing any visible movement on the user's screen.

3. Simulating Springs

Dynamic Animation allows you to easily add spring dynamics to your animations. In other words, it can help you create animations that make your widgets bounce, stretch, and squash in ways that feel natural.

To keep things simple, let's now reuse our layout's ImageView and apply a spring-based animation to it. To allow the user to initiate the animation, however, you'll need to add another Button widget to the layout.

To create a spring-based animation, you must use the SpringAnimation class. Its constructor too expects a View object and an animatable property. The following code creates a SpringAnimation instance configured to animate the x-coordinate of the ImageView:

To control the behavior of a spring-based animation, you'll need a spring. You can create one using the SpringForce class, which allows you to specify the resting position of the spring, its damping ratio, and its stiffness. You can think of the damping ratio as a constant that, like friction, is responsible for slowing the animation down until it stops. The stiffness, on the other hand, specifies how much force is required to stretch the spring.

If all that sounds a bit too complicated, the good news is that the SpringForce class offers several intuitively named constants you can use to quickly configure your spring. For instance, the following code creates a spring that is both very bouncy and very flexible:

In the above code, you can see that we've set the value of the final resting position of the spring to the initial X-coordinate of the ImageView. With this configuration, you can imagine that the ImageView is attached to a tight, invisible rubber band, which quickly pulls the ImageView back to its original position every time it is moved.

You can now associate the spring with the SpringAnimation instance using the setSpring() method.

Lastly, before starting the animation, you must make sure you give it a large initial velocity using the setStartVelocity() method.

If you run the app now, you should see something like this:

 

4. Listening to Animation Events

An animation that's created using the Dynamic Animation library must always be started from the UI thread. You can also be sure that it will start as soon as you call the start() method. However, it runs asynchronously. Therefore, if you want to be notified when it ends, you must attach an OnAnimationEndListener object to it using the addEndListener() method.

To see the listener in action, let's change the Material icon the ImageView displays every time the spring-based animation, which we created in the previous step, starts and ends. I suggest you use the ic_sentiment_very_satisfied_black_56dp icon when the animation starts, and the ic_sentiment_neutral_black_56dp icon when it ends. The following code shows you how:

With the above code, the animation will look like this:

 

5. Animating Multiple Properties

The constructors of both the FlingAnimation and the SpringAnimation classes can only accept one animatable property. If you want to animate multiple properties at the same time, you can either create multiple instances of the classes, which can get cumbersome, or create a new custom property that encapsulates all your desired properties.

To create a custom animatable property, you must create a subclass of the FloatPropertyCompat class, which has two abstract methods: setValue() and getValue(). As you might have guessed, you can update the values of all your desired animatable properties inside the setValue() method. Inside the getValue() method, however, you must return the current value of any one property only. Because of this limitation, you'll usually have to make sure that the values of the encapsulated properties are not completely independent of each other.

For example, the following code shows you how to create a custom property called scale, which can uniformly animate both the SCALE_X and SCALE_Y properties of a widget:

Now that the custom property is ready, you can use it like any other animatable property. The following code shows you how to create a SpringAnimation object with it:

While creating an animation that uses a custom property, it is a good idea to also call the setMinimumVisibleChange() method and pass a meaningful value to it in order to make sure that the animation doesn't consume too many CPU cycles. For our animation, which scales a widget, you can use the following code:

Here's what the custom property animation looks like:

 

Conclusion

You now know the basics of working with Dynamic Animation. With the techniques you learned in this tutorial, you can create convincing physics-based animations in a matter of minutes, even if you have very little knowledge of Newtonian physics.

To learn more about Dynamic Animation, refer to the official documentation. In the meantime, check out some of our other recent posts on Android app development!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.