Android Animations | Everything about android animations
By: Golap Gunjan Barman
Tags: Android App Development, Animation, Android, AndroidDev, Android Animations

In this tutorial, we’re going to implement animations in android. The animation is the process of creating motion and shape change. Animation in android is possible in many ways. In this tutorial, we will discuss one easy and widely used way of making animation called Tweened animation.

Tween Animation

The Tween Animation takes some parameters such as start value, end value, size, time duration, rotation angle, etc, and perform the required animation on that object. It can be applied to any type of object. So to use this, android has provided us a class called Animation.

To perform animation in android, we are going to call a static function loadAnimation() of the class AnimationUtils. We are going to receive the result in an instance of the Animation Object. Its syntax is as follows –

Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.myanimation);

Android Animation

The basic ways of animation that we’ll look upon in this tutorial:

Zoom In

Zoom Out

Fade In

Fade Out

Slide Left

Slide Right

Slide Up

Slide Down

Zoom In + Fade In

Zoom Out + Fade Out

Rotate

Move

Android Animation Example XML

We create a Resource Directory under the res directory names anim to hold all XML files containing the animation logic. Following is a simple XML file showing an android animation code logic

fade_in.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <alpha android:duration=”1000" android:fromAlpha=”0" android:toAlpha=”1" android:interpolator=”@android:anim/accelerate_interpolator”/> </set>

android: interpolator : It is the rate of the change in animation. We can define our own interpolator. Here we’ll use the inbuild interpolator.

: It is the rate of the change in animation. We can define our own interpolator. Here we’ll use the inbuild interpolator. android: duration : Duration of the animation in which the animation should complete. Here 1000ms is used.

: Duration of the animation in which the animation should complete. Here 1000ms is used. android:fillAfter : this property specifies whether the view should be visible or hidden at the end of the animation. If you set the value to false, the element changes to its previous state after the animation.

: this property specifies whether the view should be visible or hidden at the end of the animation. If you set the value to false, the element changes to its previous state after the animation. android:fromTRANSFORMATION & android:toTRANSFORMATION : these properties are used to start and end the animations.

& : these properties are used to start and end the animations. android:repeatMode : to repeat the animation.

: to repeat the animation. android:repeatCount : this defines the number of repetitions on animation.

Loading animation when UI widget is clicked

The main aim is to show the animation when any widget (let’s say an ImageView) is clicked. For that, we need to use the Animation class. The XML file that contains the animation logic is loaded using AnimationUtils class by calling the loadAnimation() function. The below snippet shows this implementation:

Animation animation; animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade_in);

To start the animation we need to call the startAnimation() function on the UI element as shown in the snippet below:

Image.startAnimation(animation);

Here we perform the animation on an Image view component by passing the type of Animation as the parameter.

Setting the Animation Listeners

These parameters are only needed when we want events like start, end, or repeat. For this, the activity must implement AnimationListener and the following methods need to overridden.

onAnimationStart : this will be triggered once the animation stared

: this will be triggered once the animation stared onAnimationEnd : this will be triggered once the animation is over

: this will be triggered once the animation is over onAnimationRepeat: this will be triggered if the animation repeats.

Android Animation Project Structure

As you can see, we’ve included all animation XML files.

All the Android Animation Examples XML code

Here I am providing sample code for the most common android animations.

Zoom In Animation

zoom_in.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <scale android:duration=”900" android:fromXScale=”0" android:fromYScale=”0" android:pivotX=”50%” android:pivotY=”50%” android:toXScale=”1" android:toYScale=”1"/> </set>

Here pivotX=”50%” and pivotY=”50%” is used to perform zoom from the center of the element.

Zoom Out Animation

zoom_out.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <scale android:duration=”900" android:fromXScale=”1" android:fromYScale=”1" android:pivotX=”50%” android:pivotY=”50%” android:toXScale=”0" android:toYScale=”0"/> </set>

Notice that android:to and android:from are opposite in zoom_in.xml and zoom_out.xml.

Fade In Animation

fade_in.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <alpha android:duration=”1000" android:fromAlpha=”0" android:toAlpha=”1" android:interpolator=”@android:anim/accelerate_interpolator”/> </set>

Here alpha references the opacity of an object. Object with a low alpha value is more transparent, while an object with a high alpha value is less transparent, more opaque. Fade-in animation is nothing but increasing the alpha value from 0 to 1.

Fade Out Animation

fade_out.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <alpha android:duration=”1000" android:fromAlpha=”1" android:toAlpha=”0" android:interpolator=”@android:anim/accelerate_interpolator”/> </set>

It is exactly opposite to fade in, where we need to decrease the alpha value from 1 to 0.

Slide Left Animation

slide_left.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <scale android:duration=”1000" android:fromXScale=”1" android:fromYScale=”1" android:interpolator=”@android:anim/linear_interpolator” android:toXScale=”0" android:toYScale=”1"/> </set>

It’s achieved by setting android:fromXScale=”1” and android:toXScale=”0” inside the scale tag.

Slide Right Animation

slide_right.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <scale android:duration=”1000" android:fromXScale=”0" android:fromYScale=”1" android:interpolator=”@android:anim/linear_interpolator” android:toXScale=”1" android:toYScale=”1"/> </set>

It’s achieved by setting android:fromXScale=”0” and android:toXScale=”1” inside the scale tag.

Slide Up Animation

slide_up.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <scale android:duration=”1000" android:fromXScale=”1" android:fromYScale=”1" android:interpolator=”@android:anim/linear_interpolator” android:toXScale=”1" android:toYScale=”0"/> </set>

It’s achieved by setting android:fromYScale=”1” and android:toXScale=”0” inside the scale tag.

Slide Down Animation

slide_down.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <scale android:duration=”1000" android:fromXScale=”1" android:fromYScale=”0" android:interpolator=”@android:anim/linear_interpolator” android:toXScale=”1" android:toYScale=”1"/> </set>

It’s achieved by setting android:fromYScale=”0” and android:toXScale=”1” inside the scale tag.

Zoom In and Fade In animation

zoom_in_fade_in.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <scale android:duration=”1000" android:fromXScale=”0" android:fromYScale=”0" android:pivotX=”50%” android:pivotY=”50%” android:toYScale=”1" android:toXScale=”1"/> <alpha android:duration=”1000" android:fromAlpha=”0" android:interpolator=”@android:anim/accelerate_interpolator” android:toAlpha=”1"/> </set>

It’s the combination of the zoom in and fade in animation.

Zoom Out and Fade Out Animation

zoom_out_fade_out.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <scale android:duration=”1000" android:fromXScale=”1" android:fromYScale=”1" android:pivotX=”50%” android:pivotY=”50%” android:toYScale=”0" android:toXScale=”0"/> <alpha android:duration=”1000" android:fromAlpha=”1" android:interpolator=”@android:anim/accelerate_interpolator” android:toAlpha=”0"/> </set>

It’s the combination of the zoom out and fade out animation.

Move Animation

move.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android" android:fillAfter=”true”> <translate android:duration=”600" android:fromXDelta=”0" android:toXDelta=”150%”/> </set>

Rotate Animation

rotate.xml

<?xml version=”1.0" encoding=”utf-8"?> <set xmlns:android=”http://schemas.android.com/apk/res/android"> <rotate android:duration=”600" android:fromDegrees=”0" android:interpolator=”@android:anim/cycle_interpolator” android:pivotY=”50%” android:pivotX=”50%” android:repeatMode=”restart” android:toDegrees=”360"/> </set>

from/toDegrees tag is used here to specify the degrees and cyclic interpolator is used.

Code

The activity_main.xml layout consists of a Linear Layout and ScrollView with TableRow in which every animation type is invoked on the image using their respective buttons. The XML is shown below:

activity_main.xml

<?xml version=”1.0" encoding=”utf-8"?> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android" xmlns:app=”http://schemas.android.com/apk/res-auto" xmlns:tools=”http://schemas.android.com/tools" android:layout_width=”match_parent” android:layout_height=”match_parent” android:orientation=”vertical” android:background=”@color/white” tools:context=”.MainActivity”> <ImageView android:id=”@+id/image” android:layout_width=”match_parent” android:layout_height=”200dp” android:src=”@drawable/animation” android:layout_gravity=”center_horizontal” android:layout_margin=”20dp” android:contentDescription=”@string/app_name” /> <ScrollView android:layout_width=”match_parent” android:layout_height=”match_parent”> <TableLayout android:layout_width=”match_parent” android:layout_height=”wrap_content” android:stretchColumns=”*”> <TableRow android:layout_width=”0dp” android:layout_height=”wrap_content” android:paddingBottom=”8dp”> <Button android:id=”@+id/buttomZoomIn” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”10dp” android:layout_marginEnd=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:text=”@string/zoom_in” android:textColor=”@color/white” /> <Button android:layout_width=”match_parent” android:layout_height=”wrap_content” android:id=”@+id/buttomZoomOut” android:text=”@string/zoom_out” android:layout_marginStart=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:layout_marginEnd=”10dp” android:textColor=”@color/white”/> </TableRow> <TableRow android:layout_width=”0dp” android:layout_height=”wrap_content” android:paddingBottom=”8dp”> <Button android:id=”@+id/buttomFadeIn” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”10dp” android:layout_marginEnd=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:text=”@string/fade_in” android:textColor=”@color/white” /> <Button android:layout_width=”match_parent” android:layout_height=”wrap_content” android:id=”@+id/buttomFadeOut” android:text=”@string/fade_out” android:layout_marginStart=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:layout_marginEnd=”10dp” android:textColor=”@color/white”/> </TableRow> <TableRow android:layout_width=”0dp” android:layout_height=”wrap_content” android:paddingBottom=”8dp”> <Button android:id=”@+id/buttomSlideLeft” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”10dp” android:layout_marginEnd=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:text=”@string/slide_left” android:textColor=”@color/white” /> <Button android:layout_width=”match_parent” android:layout_height=”wrap_content” android:id=”@+id/buttomSlideRight” android:text=”@string/slide_right” android:layout_marginStart=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:layout_marginEnd=”10dp” android:textColor=”@color/white”/> </TableRow> <TableRow android:layout_width=”0dp” android:layout_height=”wrap_content” android:paddingBottom=”8dp”> <Button android:id=”@+id/buttomSlideUp” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”10dp” android:layout_marginEnd=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:text=”@string/slide_up” android:textColor=”@color/white” /> <Button android:layout_width=”match_parent” android:layout_height=”wrap_content” android:id=”@+id/buttomSlideDown” android:text=”@string/slide_down” android:layout_marginStart=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:layout_marginEnd=”10dp” android:textColor=”@color/white”/> </TableRow> <TableRow android:layout_width=”0dp” android:layout_height=”wrap_content” android:paddingBottom=”8dp”> <Button android:id=”@+id/buttomZoomInFadeIn” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”10dp” android:layout_marginEnd=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:text=”@string/zoom_in_fade_in” android:textColor=”@color/white” /> <Button android:layout_width=”match_parent” android:layout_height=”wrap_content” android:id=”@+id/buttomZoomOutFadeOut” android:text=”@string/zoom_out_fade_out” android:layout_marginStart=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:layout_marginEnd=”10dp” android:textColor=”@color/white”/> </TableRow> <TableRow android:layout_width=”0dp” android:layout_height=”wrap_content” android:paddingBottom=”8dp”> <Button android:id=”@+id/buttomRotate” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”10dp” android:layout_marginEnd=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:text=”@string/rotate” android:textColor=”@color/white” /> <Button android:layout_width=”match_parent” android:layout_height=”wrap_content” android:id=”@+id/buttomMove” android:text=”@string/move” android:layout_marginStart=”5dp” android:background=”@drawable/button_ripple” android:fontFamily=”@font/poppins” android:layout_marginEnd=”10dp” android:textColor=”@color/white”/> </TableRow> </TableLayout> </ScrollView> </LinearLayout>

The MainActivity.java file contains the onClick Listeners for every button related to its animation type. It’s source code is given below:

package com.codewithgolap.androidanimation; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.animation.AnimationUtils; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final ImageView image = findViewById(R.id.image); // zoom in animation findViewById(R.id.buttomZoomIn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.zoom_in )); } }); // zoom out animation findViewById(R.id.buttomZoomOut).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.zoom_out )); } }); // fade in animation findViewById(R.id.buttomFadeIn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.fade_in )); } }); // fade out animation findViewById(R.id.buttomFadeOut).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.fade_out )); } }); // slide left animation findViewById(R.id.buttomSlideLeft).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.slide_left )); } }); // slide right animation findViewById(R.id.buttomSlideRight).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.slide_right )); } }); // slide up animation findViewById(R.id.buttomSlideUp).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.slide_up )); } }); // slide down animation findViewById(R.id.buttomSlideDown).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.slide_down )); } }); // zoom in and fade in animation findViewById(R.id.buttomZoomInFadeIn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.zoom_in_fade_in )); } }); // zoom out and fade out animation findViewById(R.id.buttomZoomOutFadeOut).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.zoom_out_fade_out )); } }); // rotate animation findViewById(R.id.buttomRotate).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.rotate )); } }); // move animation findViewById(R.id.buttomMove).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { image.startAnimation(AnimationUtils.loadAnimation( getApplicationContext(), R.anim.move )); } }); } }

As discussed above each imageView animation is started by invoking the respective animation object in which the animation logic is loaded by AnimationUtils.loadAnimation() method.

Below is the result of the all animations.

Output