Showing posts with label Android code sample: AnimationDrawable. Show all posts
Showing posts with label Android code sample: AnimationDrawable. Show all posts

Tuesday, August 12, 2014

AnimationDrawable example: determine end of animation to start another animation

This another example of "Detect AnimationDrawable.isRunning() to toggle start/stop animation" to start another animation when the first animation end.


There are no listener method to be called when animation of AnimationDrawable end. So we have to determine the duration by adding all frame duration of the animation, by calling our getAnimationDuration(AnimationDrawable src), then start a delayed runnable() to start another animation.

Download the PNGs to drawable folder:







Create animations in /res/anim/ folder:

anim_android.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >

    <item
        android:drawable="@drawable/android_1"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_2"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_3"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_4"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_5"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_6"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_7"
        android:duration="100"/>

</animation-list>

anim_android2.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >

    <item
        android:drawable="@drawable/android_7"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_6"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_5"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_4"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_3"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_2"
        android:duration="100"/>
    <item
        android:drawable="@drawable/android_1"
        android:duration="100"/>

</animation-list>

/res/layout/activity_main.xml
<LinearLayout 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"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidanimation.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Button
        android:id="@+id/startstopanimation"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Start/Stop Animation" />

    <ImageView
        android:id="@+id/myanimation1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@anim/anim_android" />
    <ImageView
        android:id="@+id/myanimation2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@anim/anim_android2" />

</LinearLayout>

MainActivity.java
package com.example.androidanimation;

import android.support.v7.app.ActionBarActivity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends ActionBarActivity {
 
 AnimationDrawable myAnimationDrawable1, myAnimationDrawable2;
 ImageView myAnimation1, myAnimation2;
 
 Handler handlerAnim2;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  myAnimation1 = (ImageView) findViewById(R.id.myanimation1);
  myAnimation2 = (ImageView) findViewById(R.id.myanimation2);
  
  myAnimationDrawable1 = (AnimationDrawable) myAnimation1.getDrawable();
  myAnimationDrawable1.stop();
  myAnimationDrawable1.setOneShot(true);
  
  myAnimationDrawable2 = (AnimationDrawable) myAnimation2.getDrawable();
  myAnimationDrawable2.stop();
  myAnimationDrawable2.setOneShot(true);

  Button startStopAnimation = (Button) findViewById(R.id.startstopanimation);
  startStopAnimation.setOnClickListener(new Button.OnClickListener() {

   @Override
   public void onClick(View v) {
    if (myAnimationDrawable1.isRunning()) {
     myAnimationDrawable1.stop();
    } else {
     myAnimationDrawable1.run();
     
     handlerAnim2 = new Handler();
     handlerAnim2.postDelayed(
      new Runnable(){

       @Override
       public void run() {
        myAnimationDrawable1.stop();
        myAnimationDrawable2.run();
       }}, 
      getAnimationDuration(myAnimationDrawable1));
    }
   }

  });
  
  
 }
 
 private int getAnimationDuration(AnimationDrawable src){
  int dur = 0;
  for(int i=0; i<src.getNumberOfFrames(); i++){
   dur += src.getDuration(i);
  }
  return dur;
 }

}


download filesDownload the files.

Wednesday, June 25, 2014

Detect AnimationDrawable.isRunning() to toggle start/stop animation

This example base on the old example "Start and Stop frame animation with AnimationDrawable". When button clicked, it read AnimationDrawable.isRunning() and call AnimationDrawable.start() or AnimationDrawable.stop() to toggle the animation.


Download the png files and copy /res/anim/anim_android.xml here.

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

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <Button
        android:id="@+id/startstopanimation"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Start/Stop Animation" />

    <ImageView 
        android:id="@+id/myanimation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@anim/anim_android"
        />

</LinearLayout>

AndroidAnimationActivity.java
package com.exercise.AndroidAnimation;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class AndroidAnimationActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ImageView myAnimation = (ImageView)findViewById(R.id.myanimation);
        final AnimationDrawable myAnimationDrawable 
         = (AnimationDrawable)myAnimation.getDrawable();
        
        Button startStopAnimation = (Button)findViewById(R.id.startstopanimation);
        
        startStopAnimation.setOnClickListener(new Button.OnClickListener(){

   @Override
   public void onClick(View arg0) {
    
    if(myAnimationDrawable.isRunning()){
     myAnimationDrawable.stop(); 
    }else{
     myAnimationDrawable.start(); 
    }

   }});

    }
}


download filesDownload the files.

Next:
Determine end of animation to start another animation

Wednesday, December 4, 2013

Start main activity after splash screen with animation

Modify from last exercise, in this post, we will start another activity (MainActivity) after animation of AnimationDrawable.

Start MainActivity after splash screen with animation


To start another activity, simple call startActivity() with intent.
   Intent intent = new Intent(
     AndroidAnimationActivity.this, MainActivity.class);
   startActivity(intent);


Create a new MainActivity.java, it's the new activity to run after splash screen. Simple display anything now.
package com.exercise.AndroidAnimation;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  ImageView image = new ImageView(this);
  image.setImageDrawable(
    getResources()
    .getDrawable(R.drawable.ic_launcher));
  setContentView(image);
 }
 
}


Modify run() method of MyTimerTask class in our splach screen activity, AndroidAnimationActivity.java in our example:
package com.exercise.AndroidAnimation;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.widget.ImageView;

public class AndroidAnimationActivity extends Activity {
    
 AnimationDrawable myAnimationDrawable;
 
 Timer timer;
 MyTimerTask myTimerTask;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ImageView myAnimation = (ImageView)findViewById(R.id.myanimation);
        myAnimationDrawable 
         = (AnimationDrawable)myAnimation.getDrawable();

        myAnimation.post(
          new Runnable(){

     @Override
     public void run() {
      myAnimationDrawable.start();
     }
          });
        
        //Calculate the total duration
        int duration = 0;
        for(int i = 0; i < myAnimationDrawable.getNumberOfFrames(); i++){
         duration += myAnimationDrawable.getDuration(i);
        }
        
        timer = new Timer();
        myTimerTask = new MyTimerTask();
        timer.schedule(myTimerTask, duration);
    }
    
    class MyTimerTask extends TimerTask {

  @Override
  public void run() {
   
   timer.cancel();
   /*
   runOnUiThread(new Runnable(){
    @Override
    public void run() {
     Toast.makeText(getApplicationContext(), 
       "Animation Stopped", 
       Toast.LENGTH_SHORT).show(); 
    }});
   */
   Intent intent = new Intent(
     AndroidAnimationActivity.this, MainActivity.class);
   startActivity(intent);
  }  
 }
}


Modify AndroidManifest.xml to add <activity> of ".MainActivity".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exercise.AndroidAnimation"
    android:versionCode="1"
    android:versionName="1.0" >

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".AndroidAnimationActivity"
            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=".MainActivity"
            android:label="@string/app_name" >
        </activity>
    </application>

</manifest>


From the demo video, it can be noted that:
- If the devie's configuration change (such as orientation) in MainActivity, it will still in MainActivity. Will not re-start the first activity.
- May be you have to special handle the BACK button depends on what you want, because of the first activity still in history stack in this simple implementation.

download filesDownload the files.

Tuesday, December 3, 2013

Handle end of animation for AnimationDrawable

I have a old exercise "Create frame animation with AnimationDrawable", which play animation repeatly without handle end of the animation. In this exercise, I will do something when the animation end.


AnimationDrawable have no any Listener for the end of animation, and also I cannot use the isRunning() method to determine the end of animation. Finally, I calculate the total duration of the animation using its getNumberOfFrames() and getDuration(). And then use Timer and TimerTask to schedule a Runnable() run when the time reached.

First of all, modify /res/anim/anim_android.xml to set android:oneshot="true", re-use the layout, main.xml, and the frame pictures. All of them can be found here.

Main code:
package com.exercise.AndroidAnimation;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.Toast;

public class AndroidAnimationActivity extends Activity {
    
 AnimationDrawable myAnimationDrawable;
 
 Timer timer;
 MyTimerTask myTimerTask;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ImageView myAnimation = (ImageView)findViewById(R.id.myanimation);
        myAnimationDrawable 
         = (AnimationDrawable)myAnimation.getDrawable();

        myAnimation.post(
          new Runnable(){

     @Override
     public void run() {
      myAnimationDrawable.start();
     }
          });
        
        //Calculate the total duration
        int duration = 0;
        for(int i = 0; i < myAnimationDrawable.getNumberOfFrames(); i++){
         duration += myAnimationDrawable.getDuration(i);
        }
        
        timer = new Timer();
        myTimerTask = new MyTimerTask();
        timer.schedule(myTimerTask, duration);
    }
    
    class MyTimerTask extends TimerTask {

  @Override
  public void run() {
   
   timer.cancel();
   runOnUiThread(new Runnable(){
    @Override
    public void run() {
     Toast.makeText(getApplicationContext(), 
       "Animation Stopped", 
       Toast.LENGTH_SHORT).show(); 
    }});
  }  
 }
}



download filesDownload the files.

Next:
Start main activity after splash screen with animation