animation

Android Animation Example

Android give us the opportunity to add animations in our applications in order to achieve a better sense of the interface quality. There are many animation types but in this tutorial we are going to use tween animations, a widely used type on Views. Tween animation define simple transformations on the components of a View object and can perform series of them. Animations can be performed through either XML or android code, but XML file is recommended because it is more reusable.

In this example we will define animations through a sequence of XML instructions in order to show simple transformations (fade, zoom, rotation and motion). Also, we will learn how to use the AnimationListener class in animations.

 

For this tutorial, we will use the following tools in a Windows 64-bit platform:

  1. JDK 1.7
  2. Eclipse 4.2 Juno
  3. Android SDK 4.4

1. Create a New Android Application Project

Open Eclipse IDE and go to File → New → Project → Android Application Project.

Specify the name of the application, the project and the package and then click Next.

AnimationsProj1

In the next window, the “Create Activity” option should be checked. The new created activity will be the main activity of your project. Then press Next button.

AnimationsProj2

In “Configure Launcher Icon” window you should choose the icon you want to have in your app. We will use the default icon of android, so click Next.

createProject3!

Select the “Blank Activity” option and press Next.

createProject4!

You have to specify a name for the new Activity and a name for the layout description of your app. The .xml file for the layout will automatically be created in the res/layout folder. Then press Finish.

createProject5!

You can see the structure of the project in the next picture.

AnimationsProjStructure

2. Create the layout of the Main Activity

As we mentioned, we want to show four simple transformations, so for each one we will define a Button that enables a specific animation. Also we will add two different contents of View, more specifically a TextView and an ImageView, in which the transformations will be performed.

Open res/layout/activity_main.xml, go to the respective xml tab and paste the following.

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity" >
   
    <Button
        android:id="@+id/fade"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:text="Fade In" />

    <Button
        android:id="@+id/rotate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/fade"
        android:layout_marginLeft="20dp"
        android:text="Rotate" />
    
     <Button
        android:id="@+id/move"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/zoom"
        android:layout_marginRight="20dp"
        android:text="Move-Intent" />
     
     <Button
         android:id="@+id/zoom"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_above="@+id/rotate"
         android:layout_alignLeft="@+id/move"
         android:text="Zoom +/-" />
    
     <TextView
         android:id="@+id/text"
         android:layout_width="wrap_content"
	     android:layout_height="wrap_content"
	     android:layout_alignParentTop="true"
	     android:layout_centerHorizontal="true"
	     android:layout_marginTop="150dp"
	     android:textAppearance="?android:attr/textAppearanceLarge"
	     android:textStyle="bold"
	     android:text="Fade In Text ..." />
     
     <ImageView
	     android:id="@+id/image"
	     android:layout_width="wrap_content"
	     android:layout_height="wrap_content"
	     android:layout_alignParentTop="true"
	     android:layout_centerHorizontal="true"
	     android:layout_marginTop="200dp"
	     android:src="@drawable/ic_launcher" />

</RelativeLayout>

3. Create the xml for the animations

We should create XML files which consist of XML notations, in order to specify animations. Each xml file should located into the anim folder of the res directory.

For this reason right click on res folder → New → Folder. Then specify the name and choose the res directory as the parent folder, like in the image below.

AnimationsProjCreate_anim

For every transformation we will create a separate XML file. Firstly, we will create the fade.xml file for defining fade in at an animation, so <alpha> tag is necessary. The attributes android:fromAlpha and android:toAlpha can take values between 0.0 and 1.0 and android:duration defines the time for an animation to be completed.

Right click on res/anim → New → Android XML File. Specify the name and choose alpha as root element.

fadeAnimationsTest

Now go to res/anim/fade.xml file, open it and paste the following.

fade.xml:

<?xml version="1.0" encoding="utf-8"?>

   <alpha xmlns:android="http://schemas.android.com/apk/res/android"
   		android:interpolator="@android:anim/accelerate_interpolator"
      	android:fromAlpha="0.0"
      	android:toAlpha="1.0" 
      	android:duration="3000" >
   </alpha>

Now, we will create the xml file for the zoom. Right click on res/anim → New → Android XML File. Specify the name as zoom and choose set as root element. Then, open res/anim/zoom.xml file and paste the following code.

zoom.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

   <scale xmlns:android="http://schemas.android.com/apk/res/android"
   		android:fromXScale="0.5"
      	android:toXScale="2.5"
      	android:fromYScale="0.5"
      	android:toYScale="2.5"
      	android:duration="3000"
      	android:pivotX="50%"
      	android:pivotY="50%" >

   </scale>


   <scale xmlns:android="http://schemas.android.com/apk/res/android"
      	android:startOffset="5000"
      	android:fromXScale="2.5"
      	android:toXScale="0.5"
      	android:fromYScale="2.5"
      	android:toYScale="0.5"
      	android:duration="3000"
      	android:pivotX="50%"
      	android:pivotY="50%" >

   </scale>

</set>

As you can see in the code above, we use two XML notations, so we have to use <set> tag. In this code we try to zoom in fist, and then to zoom out. For this reason <scale> tag is used in both situations. We set pivotX="50%" and pivotY="50%" because we want to have zoom from the center of the View object. Also, android:fromXScale, android:fromYScale, android:toXScale and android:toYScale elements define the start and the end size of the object, when we zoom in and out respectively.

For rotate transformation, <rotate> tag is used. We can specify the type of the rotation (clockwise or anti-clockwise) and the rotation angles by setting the android:fromDegrees and android:toDegrees attributes with the appropriate values. For clockwise rotation we should set positive values to android:fromDegrees and android:toDegrees attributes, while the opposite happens for anti-clockwise rotation.

In the same way, right click on res/anim → New → Android XML File. Specify the name as rotate and choose set as root element. Then, open res/anim/rotate.xml file and paste the following code.

rotate.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

   <rotate xmlns:android="http://schemas.android.com/apk/res/android"
   		android:fromDegrees="0"
      	android:toDegrees="360"
      	android:pivotX="50%"
      	android:pivotY="50%"
      	android:duration="1000" >

   </rotate>

   <rotate xmlns:android="http://schemas.android.com/apk/res/android"
      	android:startOffset="1500"
      	android:fromDegrees="360"
      	android:toDegrees="0"
      	android:pivotX="50%"
      	android:pivotY="50%"
      	android:duration="1000" >

   </rotate>

</set>

Finally, <translate> tag is used for vertical and/or horizontal motion. In our example we use android:fromXDelta and android:toXDelta attributes to define the offset in percentage (%p). The respective attributes (android:fromYDelta and android:toYDelta) exist for a vertical movement.

In the same way, right click on res/anim → New → Android XML File. Specify the name as move and choose set as root element. Then, open res/anim/move.xml file and paste the following.

move.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  	android:interpolator="@android:anim/accelerate_interpolator" >
    
    <translate  xmlns:android="http://schemas.android.com/apk/res/android"
    	android:fromXDelta="-75%p"
        android:toXDelta="75%p"
        android:duration="2000" >
        
    </translate>
    
     <translate  xmlns:android="http://schemas.android.com/apk/res/android"
     	android:startOffset="800"
        android:fromXDelta="75%p"
        android:toXDelta="-75%p"
        android:duration="2000" >
        
    </translate>
    

</set>

It is very important to mention that we can make more complex animations by using a sequence of the above tags-transformations by setting the attributes with the appropriate values. To have this result we must use the <set> tag.

4. Code the Main Activity

In our example, we are going to enable each animation which is defined in the above XML files, by pressing the appropriate Button. Also, we will use a different approach for motion animation. We are going to use an explicit Intent which implements the AnimationListener class.

In order to perform animation, the xml animation should be loaded. For this reason loadAnimation() of the AnimationUtils class is called. The loadAnimation() method returns an Animation object. Then, startAnimation() method is called in order to start the instance of that animation object.

Open src/com.javacodegeeks.android.animationstest/MainActivity.java file and paste the code below.

MainActivity.java:

package com.javacodegeeks.android.animationstest;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

	private Button fade;
	private Button zoom;
	private Button moveIntent;
	private Button rotate;
	private TextView mytext;
	private ImageView myimage;
	
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      
      mytext = (TextView) findViewById(R.id.text);
      myimage = (ImageView) findViewById(R.id.image);
      
      fade = (Button) findViewById(R.id.fade);
      fade.setOnClickListener(new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			fadeAnimation(v);
		}
      });
      
      zoom = (Button) findViewById(R.id.zoom);
      zoom.setOnClickListener(new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			zoomAnimation(v);
		}
      });
      
      moveIntent = (Button) findViewById(R.id.move);
      moveIntent.setOnClickListener(new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			moveAnimation(v);
		}
      });
      
      rotate = (Button) findViewById(R.id.rotate);
      rotate.setOnClickListener(new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			rotateAnimation(v);
		}
      });
   }

   private void fadeAnimation(View view) {
	   Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade);
       mytext.startAnimation(animation);
   }
   
   private void zoomAnimation(View view) {
	   Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.zoom);
       myimage.startAnimation(animation);
   }
   
   private void rotateAnimation(View view) {
	   Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.rotate);
       myimage.startAnimation(animation);
   }
   
   private void moveAnimation(View view) {
	   try{
	   		Intent intent = new Intent(this, MoveActivity.class);
	   		startActivity(intent);
	   }catch(Exception e) {
		   Toast.makeText(getApplicationContext(), "Error with the Intent", 
				   Toast.LENGTH_SHORT).show();
		   e.printStackTrace();
	   }
   }

}

5. Code the explicit Intent with animation listener

This Activity will implement the AnimationListener, which receives notifications when animation events occur. When AnimationListener is used, we should override onAnimationStart(), onAnimationEnd() and onAnimationRepeat() functions. It is important to mention that AnimationListener is optional, because we can perform an animation by using the above way that we showned.

Right click on src/com.javacodegeeks.android.animationstest package → New → Class and then specify the name and the new file, as shown in the next picture.

MoveActcreateClass

Now open src/com.javacodegeeks.android.animationstest/MoveActivity.java file and paste the following.

MoveActivity.java:

package com.javacodegeeks.android.animationstest;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MoveActivity extends Activity implements AnimationListener {

	private TextView movetxt;
	private Button startBtn;
	
	private Animation animation;
	
	protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.move_view);
 
        // load the animation
        animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.move);
         
        // set animation listener
        animation.setAnimationListener(this);

        movetxt = (TextView) findViewById(R.id.moveText);
        startBtn = (Button) findViewById(R.id.start);
        startBtn.setOnClickListener(new OnClickListener() {
 
            @Override
            public void onClick(View v) {
                // start the animation
                movetxt.startAnimation(animation);
            }
        });
 
    }
	@Override
	public void onAnimationEnd(Animation an) {
		// when animation ends
		 if (an == animation) {
	            Toast.makeText(getApplicationContext(), "Animation Stopped",
	                    Toast.LENGTH_SHORT).show();
	     }
	}

	@Override
	public void onAnimationRepeat(Animation an) {
		// if the animation repeats
		if (an == animation) {
            Toast.makeText(getApplicationContext(), "Animation Repeated",
                    Toast.LENGTH_SHORT).show();
		}
	}

	@Override
	public void onAnimationStart(Animation an) {
		// when the animation is started
		if (an == animation) {
            Toast.makeText(getApplicationContext(), "Animation Started",
                    Toast.LENGTH_SHORT).show();
		}
	}

}

6. Create the layout of the explicit Intent

The interface of the MoveActivity will be very simple. We want to have a Button, which indicates the start of the animation, and a TextView that will be for the performance of the animation.

To create the file for the layout, right click on res/layout → New → Android XML File. Specify the name as move_view and choose LinearLayout as the root element.

move_viewAnimationTest

Open res/layout/move_view.xml, go to the xml tab and paste the following.

move_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

     <TextView
         android:id="@+id/moveText"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="20dp"
         android:text="Javacodegeeks"
         android:textAppearance="?android:attr/textAppearanceLarge"
         android:textStyle="bold" />

     <Button
         android:id="@+id/start"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="20dp"
         android:text="Start the animation" />

</LinearLayout>

7. Define the new Activity

Now we have to define the MoveActivity in our AndroidManifest file.

Open AndroidManifest.xml file and go to the respective xml tab. Then paste the code below.

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javacodegeeks.android.animationstest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.javacodegeeks.android.animationstest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
             android:name="com.javacodegeeks.android.animationstest.MoveActivity"
            android:label="AnimationsTest: Move-Intent" >
            
        </activity>
    </application>

</manifest>

8. Run the application

To run our application, right click on our project → Run as → Android Application. The AVD will appear with the app loaded, as you can see in the picture below.

AVDAnimationsTest1

To see how this application works, we will show some instances of the animations.

Lets press “Fade In” button. As you can see in the next image, the TextView “Fade In Text…” is fading in.

AVDAnimationsTest2

If we press the “Zoom +/-” button, the image will zoom in and then it will zoom out until it reaches it’s original size.

AVDAnimationsTest3

In parallel if we click the “Rotate” button, the image will start rotate clockwise and then anti-clockwise. In the next picture you can see an instance of the rotation of the ImageView.

AVDAnimationsTest4

Now lets press “Move-Intent” button. The MoveActivity of the explicit Intent will launch.

AVDAnimationsTest5

If we press the “Start Animation” button, the text will begin to move horizontally and the onAnimationStart() method will be called.

AVDAnimationsTest6

When the motion of the text stops, the onAnimationEnd() method is called by the AnimationListener, as you can see in the image below.

AVDAnimationsTest7

Download Eclipse Project

This was an example of Animation in Android. Download the Eclipse Project of this example: AnimationsTest.zip

Katerina Zamani

Katerina has graduated from the Department of Informatics and Telecommunications in National and Kapodistrian University of Athens (NKUA) and she attends MSc courses in Advanced Information Systems at the same department. Currently, her main academic interests focus on web applications, mobile development, software engineering, databases and telecommunications.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Sabina
3 years ago

Thanks a lot! It helped me to finally get a grip with animations, it never worked before ;-)

Back to top button