A beginners guide to implement Android Animations — Part 1 (2 part series)
original source : https://medium.com/@shubham.bestfriendforu/a-beginners-guide-to-implement-android-animations-part-1-2-part-series-b5fce1fc85
my review point is 9/10
Admit it, you always wanted to create visually appealing apps. But due to functionality first approach, animations were always procrastinated. Not any more.
A little basics about animations:
There are 3 types of Animations:
- Property Animations — They are used to alter property of objects (Views or non view objects). We specify certain properties(like translateX, TextScaleX) of the objects to change. Various characteristics of animation which can be manipulated are animation duration, whether to reverse it and for how many times we want to repeat the animation etc. They were introduced in Android 3.0 (API level 11).
- View Animations — They are used to do simple animations like changing size, position, rotation, control transparency. They are easy to build and are very fast but have their own constraints. For eg — Their state changes but their property does not change. View animations will be covered in part 2.
- Drawable Animations — This is used to do animation using drawables. An XML file specifying various list of drawables is made which are run one by one just like a roll of a film. This is not much used so I won’t cover it.
Android 5.0 introduced various other animations — Reveal Effect, Activity/Fragment transitions, Shared Element transitions etc. Click here to learn more about this.
Note — Part 1 will discuss Property Animations only.
When to use which type of Animation
- If you just want to do simple animations on views without having to handle other details like touch or click, use View Animations. The problem with View Animations is that, though the View state changes, its property still remains at the original position. That means, if a ImageButton is moved from 0 to 100 pixels to the right, though it will animate to right, the touch(property) of image button will still be at 0th position.
- View Animations can be used in Splash screens. When using View Animations, use XML instead of doing it programmatically. Using XML files, it is more readable and can be shared among other views.
- If you want to handle touch, click after the animation, go for Property Animation as they change the state as well as behaviour.
Property Animation Concepts

The actual animation is done by Value Animator. This class keeps track of animation duration and the current value of the property that it is animating. TimeInterpolater keeps track about the time(speed) of animation like whether it is with constant speed in the given time, or accelerate then decelerate in the given time. TypeEvaluator is used to calculate fractions based on the type of TypeEvalutor used for eg, int, float, rgb etc. We can use a custom TypeEvaluator also if none matches our needs.
Animations Using ValueAnimator
The ValueAnimator
class lets you animate values of some type for the duration of an animation by specifying a set of int
, float
, or color values to animate through. You obtain a ValueAnimator
by calling one of its factory methods: ofInt()
, ofFloat()
, or ofObject()
. For example:
final TextView animateTextView = (TextView)findViewById(R.id.tv_animate);
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 500f);
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); // increase the speed first and then decrease
valueAnimator.setDuration(2000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
animateTextView.setTranslationY(progress);
// no need to use invalidate() as it is already present in //the text view.
}
});
valueAnimator.start();

he same thing can be achieved using XML code as follows:
/res/animator/value_animator_ex.xml
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:valueFrom="0f"
android:valueTo="500f"
android:valueType="floatType" />
----Activity Code----
ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(
this, R.animator.value_animator_ex);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
animateTextView.setTranslationY(progress);
}
});
valueAnimator.start();
Animations Using ObjectAnimator
The ObjectAnimator
is a subclass of the ValueAnimator
and combines the timing engine and value computation of ValueAnimator
with the ability to animate a named property of a target object. This makes animating any object much easier, as you no longer need to implement the ValueAnimator.AnimatorUpdateListener
, because the animated property updates automatically. In most cases, we should use this.
For the same animation above, we can write the code for ObjectAnimator as:
TextView animateTextView = (TextView) findViewById(R.id.tv_animate);
ObjectAnimator textViewAnimator = ObjectAnimator.ofFloat(animateTextView, "translationY",0f,500f);
textViewAnimator.setDuration(2000);
textViewAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
textViewAnimator.start();
As we can see, we didn’t have to use listener to update position of text view as this is done by ObjectAnimator itself. The main thing here to see is “translationY” which is the property we want to perform animation on. This should be a defined property in android or if it is our own property then we must specify its accessor methods i.e. getter and setter method.
The same thing can be implemented using XML as:
/res/animator/object_animator_ex.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000" android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:propertyName="translationY"
android:valueFrom="0f"
android:valueTo="500f"
android:valueType="floatType" />
----Activity Code----
TextView animateTextView = (TextView) findViewById(R.id.tv_animate);
ObjectAnimator textViewAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(AnimationActivity.this, R.animator.object_animator_ex);
textViewAnimator.setTarget(animateTextView);
textViewAnimator.start();
Doing Multiple Animations at a time
We can have multiple ObjectAnimators start at same time and for the same duration to do multiple animations, but it is not efficient as no view knows about any other view. To do the same we can use AnimatorSet class.
In my current project, I have done the following animation:
(Will be updated soon. Sorry for the inconvenience.)
As we can see, there are multiple animations running at the same time. There are 4 simultaneous animations going on. When the search icon is clicked, first the search icon is moving to the left, the logo is fading out, cancel button is fading in and edit text is also fading in. On clicking cancel button, the same animation is played but in reverse.
The code to do this is:
---------perform animation on search icon click ----------
// take to leftmost position
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int modifierX = -(displayMetrics.widthPixels - v.getWidth());
private static final int SEARCH_ANIMATION_DURATION = 1000; // 1 sec
ObjectAnimator searchIconLeftAnimation = ObjectAnimator.ofFloat(v, "translationX", modifierX);
searchIconLeftAnimation.setDuration(SEARCH_ANIMATION_DURATION);
ObjectAnimator logoFadeOutAnimator = ObjectAnimator.ofFloat(mAppLogo, "alpha", 1f, 0f);
logoFadeOutAnimator.setDuration(SEARCH_ANIMATION_DURATION);
ObjectAnimator cancelImageFadeInAnimator = ObjectAnimator.ofFloat(mIvCancelSearch, "alpha", 0f, 1f);
cancelImageFadeInAnimator.setDuration(SEARCH_ANIMATION_DURATION);
ObjectAnimator searchEditTextAnimator = ObjectAnimator.ofFloat(mEtSearch, "alpha", 0f, 1f);
searchEditTextAnimator.setDuration(SEARCH_ANIMATION_DURATION);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(searchIconLeftAnimation).with(logoFadeOutAnimator);
animatorSet.play(searchIconLeftAnimation).with(cancelImageFadeInAnimator);
animatorSet.play(searchIconLeftAnimation).with(searchEditTextAnimator);
animatorSet.start();
---------reverse all the animations on cancel click ----------
ObjectAnimator searchIconRightAnimation = ObjectAnimator.ofFloat(mIvSearch, "translationX", 0);
searchIconRightAnimation.setDuration(SEARCH_ANIMATION_DURATION);
ObjectAnimator logoFadeInAnimator = ObjectAnimator.ofFloat(mAppLogo, "alpha", 0f, 1f);
logoFadeInAnimator.setDuration(SEARCH_ANIMATION_DURATION);
ObjectAnimator cancelImageFadeOutAnimator = ObjectAnimator.ofFloat(mIvCancelSearch, "alpha", 1f, 0f);
cancelImageFadeOutAnimator.setDuration(SEARCH_ANIMATION_DURATION);
ObjectAnimator searchEditTextFadeInAnimator = ObjectAnimator.ofFloat(mEtSearch, "alpha", 1f, 0f);
searchEditTextFadeInAnimator.setDuration(SEARCH_ANIMATION_DURATION);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(searchIconRightAnimation).with(logoFadeInAnimator);
animatorSet.play(searchIconRightAnimation).with(cancelImageFadeOutAnimator);
animatorSet.play(searchIconRightAnimation).with(searchEditTextFadeInAnimator);
animatorSet.start();
Here we have created multiple Object Animators on different views and played them together using AnimatorSet. Methods like play() and with() helps to achieve this.
We can also use listeners to determine about the animation status. For eg:
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
// do anything before animation start
}
@Override
public void onAnimationEnd(Animator animation) {
// do other stuff after animation ends
}
@Override
public void onAnimationCancel(Animator animation) {
// do something when animation is cancelled (by user/ developer)
}
@Override
public void onAnimationRepeat(Animator animation) {
// do something when animation is repeating
}
});
When performing multiple animations on a single view
Till now, we have seen animations on different view objects. We can perform multiple animations on a single view using the above approaches also (using animator set), but it is a performance overhead as there is the processing overhead of setting up the AnimatorSet and running two Animators in parallel. A better approach is to use ViewPropertyAnimator. Using this, the code is simpler to read also. For eg:
animateTextView.animate().rotation(360f).y(500f).setDuration(2000);
----------------------------VS-----------------------------
ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat(animateTextView, "rotation", 360f);
rotationAnimator.setDuration(2000);
ObjectAnimator translateAnimator = ObjectAnimator.ofFloat(animateTextView, "translationY", 500f);
translateAnimator.setDuration(2000);
AnimatorSet set = new AnimatorSet();
set.playTogether(rotationAnimator,translateAnimator);
set.start();
Does animation makes my app slow or will it surpass the 16ms draw window time? Is there any overhead on the performance ?
Animators that update the UI cause extra rendering work for every frame in which the animation runs. For this reason, using resource intensive animations can negatively impact the performance of your app.
Work required to animate your UI is added to the animation stage of the rendering pipeline. You can find out if your animations impact the performance of your app by enabling Profile GPU Rendering and monitoring the animation stage.
Think about the use case and then apply the appropriate way.
Thanks for reading the article. Suggestions/ Corrections/ Comments are always welcomed. If you like it, please hit the like button and share the article with the Android community. Let’s share the knowledge as much as we can.
Note — Part 2 on ViewAnimations is also coming very soon.
part2
In Part 1, we discussed about basics of Animations and about Property Animations. In this post, I’ll discuss about View Animations and the new Activity transitions framework introduced in API level 21. The transition framework was already added in API Level 19 (4.4.2) but it got more powerful in API level 21.
The android framework began with View animations but due to their problems, they introduced the Property Animations as discussed in Part 1. View animations are perfect for splash screen animations and other areas where there is no such interaction with the view. In most of the cases, they are implemented using XML code.
Types of View Animation
- Tween Animation — These are the animations applied on a view which is responsible for scaling, translating, rotating or fading a view (either together or one by one).
- Frame Animation — These animations are applied using various drawables. In this, we just have to specify a list of drawables in the XML code and the animation runs just like frames of a video.
View Animations are not much used because the same thing can be using ViewPropertyAnimator object which is much faster and readable. Frame animation is similar to Drawable Animation. The more important thing is to understand the new Transition framework which is much useful and provide beautiful animations.
The new animations (API Level 21+)

Android provides activity transitions, fragment transitions and shared element transitions. Other animations are circular reveal, ripple effect etc, curved motion. Ripple effect can be applied by just setting the background property of a view as:
android:background=”?attr/selectableItemBackground”
Here we will try out activity transitions and shared element transitions just like above GIF.
The basic step is to create styles-v21 file and do the following things:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="AppTheme" parent="BaseTheme"> <!-- enable activity transitions --> <item name="android:windowActivityTransitions">true</item> <!-- enable window content transitions --> <item name="android:windowContentTransitions">true</item> <!-- specify enter and exit transitions --> <item name="android:windowEnterTransition">@transition/custom_animation</item> <item name="android:windowExitTransition">@transition/custom_animation</item> <!-- if we don't specify reenter transition, by default exit transition is taken --> <!-- if we don't specify return transition, by default enter transition is taken --> <!-- specify shared element transitions --> <item name="android:windowSharedElementEnterTransition">@android:transition/move</item> <item name="android:windowSharedElementExitTransition">@android:transition/move</item> </style> </resources>

Shared Element Transitions — In this, there is a shared view between two activities/ fragments. Shared view means that both the views are same in both the activities, it’s just that their sizes are a little different. For eg — an image in a recycler view item which when clicked(tapped) show the item detail with the same image but in larger size. We will do something like this:-

Cool…But how is this thing working?
Basically there are 2 activities here. One with a small dot and other with a big dot and text. When I click the button in Activity A, it opens up the Activity B with the animation. This effect can also be seen in the Google Play Store app. But they also apply circular reveal, arc motion effects. The most important thing to notice here that the image is NOT moving from original position to final position. The transition framework calculates the start scene and the end scene and then animates in between those scenes. For knowing how animations work refer this. Also with the help of new intent mechanism, this is achievable as shown below:
@Override public void onClick(View v) { if (v instanceof Button) { ImageView circleImage = (ImageView) findViewById(R.id.iv_circle); Intent intent = new Intent(AnimationActivity.this,ImageDetailActivity.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { startActivity(intent, ActivityOptions.makeSceneTransitionAnimation( this, new Pair<View, String>(circleImage, ViewCompat.getTransitionName(circleImage))) .toBundle()); } else { startActivity(intent); } } }
Here I’ve used the API check for lollipop and then run the transition and in other levels the activity will start normally. The new Pair<> line helps the system to know about the shared elements.
Note — Keep the transition name same in both the views (small dot and big dot). This helps the system know the shared elements. A good thing is to place the transition name in strings.xml.
<?xml version="1.0" encoding="utf-8"?> <explode xmlns:android="http://schemas.android.com/apk/res/android"> <targets> <target android:excludeId="@android:id/statusBarBackground" /> <target android:excludeId="@id/toolbar_container" /> </targets> </explode>
Here, I’ve used custom_animation.xml transition for the activity transition which is an explode effect. More over, I’ve excluded some views to participate in animation. These views are the statusBar and the toolbar. We can use different kinds of effect (fade, slide) to match our use case.
Activity Transitions — API level 21 introduced more realistic and user friendly activity transitions. For instance, Explode, ChangeImageTransformtransitions appear more realistic and better guide the user of the activities flow. In our example above I’ve used fade transition which is provided by Android system. If we don’t specify any animation, then by default AutoTransition is used. We can create our own transition by creating a custom class that extends Transition. See this for reference.
Circular Reveal

The above circular reveal effect is created when FAB is clicked:
/* create a new circular reaveal on the give view. This view is initially invisible. In this case the view covers full screen */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void createCircularReveal(final View view) { // to get the center of FAB int centerX = (int) mFab.getX() + mFab.getWidth() / 2; int centerY = (int) mFab.getY(); float finalRadius = (float) Math.hypot(view.getWidth(), view.getHeight()); // starts the effect at centerX, center Y and covers final radius Animator revealAnimator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, 0, finalRadius); view.setVisibility(View.VISIBLE); revealAnimator.start(); } /* hides the circular view */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void hideCircularReveal(final View myView) { // get the center for the clipping circle int cx = (int) mFab.getX() + mFab.getWidth() / 2; int cy = (int) mFab.getY(); // get the initial radius for the clipping circle float initialRadius = (float) Math.hypot(myView.getWidth(), myView.getHeight()); // create the animation (the final radius is zero) Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); // make the view invisible when the animation is done anim.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { myView.setVisibility(View.INVISIBLE); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); // start the animation anim.start(); }
Thanks for reading the article. Suggestions/ Corrections/ Comments are always welcomed. If you like it, please hit the like button and share the article with the Android community. Let’s share the knowledge as much as we can.