Getting to know property animations
Jump straight to the tutorial or continue for a quick introduction to Property Animations.
The easiest way to animate an object is to use the ObjectAnimator class. We’ll show you how when we discuss our tutorial app.
Simply construct your ObjectAnimator object by passing the constructor three parameters:
- The object that you want to animate
- The name of the property that you want to animate
- A set of values between which you want to animate the property over time
The property that you want to animate must have getter and setter functions:
- set<propertyName> - this function is used to update the property during the animation. If it doesn’t have a setter function then you can add one to the class, use a wrapper class or use the ValueAnimator class instead of an ObjectAnimator
- get<propertyName> - if you only pass one value as the last parameter when you construct your ObjectAnimator object, the system assumes that this is the end value. It then needs to use a getter function to get the start value
You can group animations together using the AnimatorSet class.
You can bundle animations together in an Animator Set. This lets you:
- start a number of animations at the same time
- start animations one-after-the other
- start animations after a time delay
- you can also put AnimatorSet objects inside other AnimatorSet objects
You can monitor the progress of an animation for critical events using an AnimatorListener.
You can register an AnimatorListener on your ObjectAnimator object, as we have done in our tutorial, to listen for:
- when the animation starts
- when the animation ends
- when the animation is repeated
- when the animation is cancelled
You can also use an AnimatorUpdateListener to listen for when the animation is updated.
If you don’t want to use all of the AnimatorListener’s methods then you can extend the AnimatorListenerAdapter class to use only the methods that you need.
Automatically run animations when your layouts change
You can use the LayoutTransition class to automatically run animations when a layout changes.
There are two changes to the layout that trigger the animation:
- trigger APPEARING animations when items are added to the layout container
- trigger DISAPPEARING animations when items are removed from the layout container
There are 4 animations that run to:
- animate the added items
- animate the removed items
- or animate items in the layout container that are affected by the items being removed or added (they move to makes space or close up the gap)
Using the type evaluator
Usually you’d animate property types recognised by the Android system, such as:
Sometimes you may have to animate an unknown property type. You can then use the TypeEvaluator interface to get the appropriate value for your animated property.
Interpolators control the speed of the animation over time.
Android has a number of interpolators that you can use:
- AccelerateDecelerateInterpolator – the default interpolator. The animation starts off fast, accelerates steadily then slows down at the end
- AccelerateInterpolator – starts slowly, then accelerates through the middle
- AnticipateInterpolator – starts backwards and then flings forwards
- AnticipateOvershootInterpolator – starts backwards, flings forwards, overshoots and then returns to the final value
- BounceInterpolator – the animation bounces at the end
- DecelerateInterpolator – starts quickly and then decelerates
- LinearInterPolator – the rate of change during the animation is constant
- OvershootInterpolator – the animation flings forward, overshoots the last value and then returns to the end value
You can also create your own interpolator by implementing the TimeInterpolator class.
You can define the specific state of an animation at a specific time using Key Frames. A KeyFrame object consists of a time/value pair.
You can also use an interpolator to control the behaviour of animations between keyframes.
You can do simple view animations using Android’s View Animation system. You may want to have a look at Using View Animations in your apps: A tutorial for how to do that.
You can also use the Property Animation system, where you have more control, to animate views.
- Simple View animations – changes the way View objects are drawn but does not change the View object
- Property View animation – changes the properties of the View object. Views also automatically call invalidate() to refresh the screen whenever their properties are changed. New properties in the View class that you can animate are:
- translationX and translationY – controls the location of the view. This value is added to the left or top coordinates of the view which are set by the layout
- rotation, rotationX and rotationY – used to control the 2D and 3D rotation of the view
- scaleX and scaleY – control the 2D scaling of a view
- pivotX and pivotY – control the location of the view’s pivot point
- x and y – these are utility properties describing the final location of the view in its container (by summing the left and top values and translationX and translationY values)
- alpha – controls the transparency of a view
Animating your Views with the ViewPropertyAnimator class
Use the ObjectAnimator if you’re only going to animate one or two properties of a View object.
Use the ViewPropertyAnimator class if you want to animate a number of properties at the same time. It provides the means to animate several properties of a view in parallel using a single Animator object.
The ViewPropertyAnimator’s code is also more concise and easier to read.
Declaring your animations in xml
Although you can declare your Property animations in code, it’s better to declare them in XML:
- It makes it easier to reuse the animations in multiple activities
- It’s easier to edit the animation sequences
You define the animation in an XML file which you save in the res/animator folder.
Here are the classes and their corresponding element tags that you can use in your property animation XML files:
- ValueAnimator - <animator>
- ObjectAnimator - <objectAnimator>
- AnimatorSet - <set>
To run the animation, use the AnimatorInflator’s loadAnimator() method to inflate the property animation resource file into an Animator object which you can then use.
For more on Property Animation resources, have a look at the Animation Resources documentation.
Starting our tutorial app displays a car with a country-scene background. There’s also a green coloured circle in the top-right of the screen.
Clicking the circle changes its color to yellow. The car’s wheels start turning and an image slides in from the right, both animations giving the impression that the car is moving.
Clicking the yellow circle changes it to red. Clicking the red circle changes it to green and stops the animations.
Screen density, size and orientation
Please note that this tutorial app was tested on a Sony Xperia V in portrait mode. If you run it on any other device where the screen density or size differs from the Xperia’s or if you run it in landscape mode, then the images will not align.
To correct this, you’ll have to:
- Supply alternative image resources for the different screen densities and sizes
- Create alternative layouts for the different screen sizes and orientation
- Realign the images in the alternative layouts
Have a look at: Designing for multiple screens. Alternative image resources for more on using images in your apps.
The car remains stationary while the wheels turn and part of the background slides across the screen to simulate movement
Make the earth move under your feet: Animating the background
The activity’s RelativeLayout container has a country scene set as its background. This does not move.
To simulate movement, we repeatedly slide two images in from the right and off on the left of the screen. The images slide behind the car and in front of the stationary background.
The static background displays a country scene. Two separate images are animated to repeatedly slide in from the right
Here’s the code for doing that:
We animate the image view, alternating the image that it displays
Note the following:
- We define the animation in code without using XML
- PROPERTY_NAME – a utility property describing the final location of the view in its container (by summing the left value and translationX value)
- setImageResource – we’re running this code in the activity’s onCreate() method where we get a reference to the image view that we want to animate. We have two images that we want to display using the same image view. Here we use setImageResource() to set the image view to display the background1 image
- isShowingBackground1 – we set this to true, indicating that we’re showing the first background image
- animatedBackgroundImage – our ObjectAnimator object which will animate our background image. We pass in 3 parameters:
- the target whose property we want to animate
- the name of the property that we want to animate
- the values that we want to animate between. They’re float values, the first is the start value and the second is the end value of the animation
- setDuration – sets the length of the animation in milliseconds. The default is 300ms
- setRepeatMode – defines what should happen when the animation ends
- ValueAnimator.RESTART – the animation will repeat if setRepeatCount() has a positive number or is set to INFINITE
- setRepeatCount – sets the number of times that the animation should be repeated
- ValueAnimator.INFINITE – repeats the animation indefinitely
- setInterpolator – sets the speed of the animation between the start and finish
- LinearInterpolator - the rate of change during the animation is constant
Your attention please! The listener
We use an AnimatorListener to listen for specific events during the animation – such as start, cancel, end and repeat. We’re only interested in when the animation starts repeating:
We put the code that we want executed when the animation starts repeating in the listener’s onAnimationRepeat() method
Note the following:
- isShowingBackground1 – we’re animating the image view and want to alternate the images shown in the view. We use an if else statement to check the value of isShowingBackground1. If the image view is set to show the first background image then we swop it with the second background image. Similarly if it’s set to show the second background image then we swop it with the first. We also reset isShowingBackground1 accordingly
Where the rubber meets the road: The wheels
We want the wheels to spin, giving the impression that the car is moving. So we place separate wheel images in front of the car’s wheels. We’ll animate these to spin.
We overlay the car’s wheels with a separate image of a wheel which we animate
It’s all done in XML
You can define your property animations in code or in XML.
We define our wheel animation in an XML file, wheel_spin.xml, which we save in the res/animator folder.
Our wheel spin animator object which we define in an XML file
Note the following:
- objectAnimator – our ObjectAnimator object is the root element
- duration – the time in milliseconds for the animation to complete
- propertyName – the name of the property that we want to animate
- repeatCount – the number of times that we want to repeat this animation. We set it to repeat forever
- valueFrom – we start the rotation from 0 degrees
- valueTo – we end the animation at 360 degrees
- valueType – we’re using float’s for the from and to values
This animator is inflated in our code when we run the animation.
Unlock the secret code
We inflate the XML animation resource into our Animator objects
Note the following:
- wheelBack – we get a reference to the back wheel image view
- backWheelAnimator – we inflate and load the wheel_spin XML animator resource into our Animator object, backWheelAnimator
- setTarget – we set the wheelBack ImageView as the target for the animation
- we do the same for the front wheel
All together now! The animator set
We use a set to group the back and front wheel animations together so that we can run them at the same time.
Use a set to group the two wheel animations together
Note the following:
- animatorSet – our AnimatorSet object that enables us to play the two wheel animations together
- playTogether – enables us to play a number of animations at the same time. We pass the animations that we want to play as parameters
- setInterpolator – we set the interpolator to use for both animations in the set to LinearInterpolator. It ensures a constant rate of change during the animation
Get a move on. Push the button
Clicking the coloured circle in the top-right of the screen, executes the changeColor() method.
The switch statement checks to see which coloured circle is showing: if it’s green then the animations start, if it’s red then the animations stop.
Here’s the switch statement code:
We use a switch statement to determine which coloured circle is showing and start or stop the animations accordingly
Note the following:
- the switch statement evaluates the value of counter and executes the appropriate case statement
- case 1 – we set the image view to show the yellow circle. We also start the animations and set the counter to 2. When the yellow circle is clicked, case 2 of the switch statement will be executed
- case 3 – this is executed when the red circle is clicked. Here we set the green circle to display and cancel both of the animations. counter is set to 1
Have you seen our Frame Animation tutorial? Frame-by-Frame Animation tutorial.
I hope that you have found this tutorial helpful.
This project was created using Android Studio.
Are you using Eclipse or another IDE? Here's how you can use this project's Android Studio files.