AndroidWith the introduction of material design, Android adopted a design language that is grounded in reality. Surfaces, edges, and shadows all work together to provide visual cues users will instinctively recognize and understand. Now, Google is releasing a new set of APIs to do the same thing for Android animations.

The new physics-based animation APIs use the laws of physics to create motion that matches the real world. These animations are driven by forces such as velocity, friction, stiffness, and more. The APIs make it easy to define these properties and create realistic motion that can be applied to just about any property of a View. Keep reading to learn how to set up the library in your project and get started adding physics to your animations. To see these APIs in action, head over to the demo project on GitHub for working examples that allow you to manipulate the animation's forces.

Dynamic Animation Support Library

To get started with the new animations, you'll first need to add the dynamic animation support library to your project. The earliest version that supports everything we'll cover here is 25.4.0, but you should use the version that matches your targetSDK. In your module's build.gradle file, just add:

dependencies {
 ...
 compile 'com.android.support:support-dynamic-animation:25.4.0'
 ...
}

Note that the support libraries are now available through Google's maven repository. You may also need to add the following to your project's build.gradle file if it isn't already there:

allprojects {
 repositories {
 	...
 maven {
 url "https://maven.google.com"
 }
 ...
 }
}

Once your dependencies are set up and the dynamic animation support library is available, you're ready to start animating. The library provides two animation classes to choose from - SpringAnimation and FlingAnimation.

SpringAnimation

The SpringAnimation class allows you to easily add spring physics to your animations. By declaring what property you want to animate and providing forces such as velocity, stiffness, and damping, we can create life-like motion that matches the bounce of a spring.

Spring animation

In the below example we'll provide "animatedView" as the view we want to animate and set the view's X translation as the property to animate. We'll also define the end point as 0 so the view will spring back to its starting point. For a complete working example of SpringAnimation, check out the demo on GitHub.

SpringAnimation springAnimation = new SpringAnimation(animatedView, DynamicAnimation.TRANSLATION_X, 0f);
springAnimation.getSpring().setStiffness(SpringForce.STIFFNESS_MEDIUM);
springAnimation.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY);
springAnimation.setStartVelocity(velocityTracker.getXVelocity());
springAnimation.start();

In addition to these properties, we also have the ability to set the animation's min and max values using the setMinValue(float) and setMaxValue(float) methods. This can be helpful to limit overshoot or to save CPU cycles by stopping the animation when it goes off screen.

SpringForce

The characteristics of a spring are defined by SpringForce. In the above example we modify the default SpringForce implementation created with each SpringAnimation, but we can also create our own and provide it to the animation.

SpringForce springForce = new SpringForce(0f);
springForce.setStiffness(SpringForce.STIFFNESS_LOW);
springForce.setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY);

SpringAnimation springAnimation = new SpringAnimation(animatedView, DynamicAnimation.TRANSLATION_X);
springAnimation.setSpring(springForce);
...

A higher stiffness will reduce how stretchable the spring is, while a higher damping ratio will slow the springs bounce down faster. The SpringForce class provides several recommended values for each of these ranging from DAMPING_RATIO_NO_BOUNCY (1.0f) to DAMPING_RATION_HIGH_BOUNCY (0.2f) and STIFFNESS_HIGH (10000.0f) to STIFFNESS_VERY_LOW (50.0f).

FlingAnimation

Now that we've got things bouncing, let's slow them down with a little friction. Just like SpringAnimation, FlingAnimation allows us to define properties such as min value, max value, and starting velocity. However, in addition to these we can also provide a friction force.

In the example below, we'll again use "animatedView" as our view and this time set the view's Y translation as the property to animate. We'll also define a friction force to slow down our starting velocity.


FlingAnimation flingAnimation = new FlingAnimation(animatedView, DynamicAnimation.TRANSLATION_Y)
 .setFriction(0.5f)
 .setStartVelocity(velocityTracker.getYVelocity());
flingAnimation.start();

With each animated frame, the defined friction force will be applied to the velocity until the two forces reach an equilibrium, ending the animation. One thing to note is that the friction value must be greater than 0 for the code to run. This limitation is in place to prevent the possibility of a fling animation running indefinitely, since without any friction there would be no force to slow down the velocity.

For a complete working example of FlingAnimation, take a look at the demo on GitHub. You'll also be able to customize the friction value to better understand the effects this can have on the motion.

Custom Physics Animations

Out of the box these APIs are capable of animating the properties belonging to a View. This includes position, translation, rotation, scale, alpha, and scroll. However, if you need to do something more custom, there are several options available to quickly add physics to your motion.

OnAnimationUpdateListener

The easiest way to access the values as they are being animated is by setting an OnAnimationUpdateListener on your animation. When set, the animation will call the listener's onAnimationUpdate(DynamicAnimation, float, float) method for each frame. This will give you access to the animated value as well as the current velocity. You can then use these values however you need to support your custom motion.

...
animation.addUpdateListener(new OnAnimationUpdateListener() {
 @Override
 public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
 // TODO - use value and velocity
 }
});
...

FloatPropertyCompat

Both SpringAnimation and FlingAnimation have constructors that accept a FloatPropertyCompat object. By creating a subclass of this type and implementing its setValue(float) and getValue() methods, you can animate custom properties or even multiple properties with matching values at the same time.

SpringAnimation springAnimation = new SpringAnimation(animateView, new FloatPropertyCompat("translationY") {
 @Override
 public float getValue(View view) {
 return view.getTranslationY();
 }

 @Override
 public void setValue(View view, float value) {
 view.setTranslationY(value);
 }
}, 0);

Take a look at the project on GitHub to see a simple working example of how to subclass FloatPropertyCompat.

Summary

Before the dynamic animation library, the Animator classes like ObjectAnimator and ValueAnimator were the main methods for creating animations on Android. However, these APIs modified their values based on time and lacked the ability to define forces. This meant developers looking to create physics-based animations had to create complex solutions of their own. With these new APIs, Google has made it easy to create animations affected by the laws of physics with just a few lines of code.

Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

Interested in finding out more about CapTech? Connect with us or visit our Career page to learn more about becoming a part of a team that is developing world-class mobile apps for some of the largest institutions in the world.

CapTech is a thought leader in the Mobile and Devices spaces, and has deployed over 300 mobile releases for Fortune 500 companies. Additionally, CapTech was identified by Forrester as one of top Business to Consumer (B2C) Mobile Services Providers in their 2016 Wave.