0

I want to change the canvas image automatically.

Means i want that canvas image should be set one after another continuously.

I have written code which sets image only once.

But i don't know the code about changing the canvas image automatically so it creates the effect like Object is running on the road..

So what is the way to create such kind of animation in canvas ?

Please give me some ideas to create such 2D animation.

Thanx in Advance.

Android_coder
  • 9,953
  • 3
  • 17
  • 23
Zankhna
  • 4,570
  • 9
  • 62
  • 103

2 Answers2

2

Check out this tutorial of frame animation:

http://www.youtube.com/watch?v=iTKtT-R98EE

More info can be found at following links:

Starting Frame-By-Frame Animation

Following is the step by step procedure:

In Frame Animation you will be swapping frames repeatedly, so that it appears continuous to the human eye and we feel that it is animated. Frame is referred to an image. So to implement frame animation one needs to have set of images, which describes a motion.

Step 1- Create a drawable folder.

Within it create an animation_list.xml file.

It includes : A list of items that has the addresses of the frame images.

<?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/blank" android:duration="210" />
<item android:drawable="@drawable/logo" android:duration="210" />
<item android:drawable="@drawable/logo1" android:duration="210" />
<item android:drawable="@drawable/logo2" android:duration="210" />
<item android:drawable="@drawable/logo3" android:duration="210" />
<item android:drawable="@drawable/logo4" android:duration="210" />
<item android:drawable="@drawable/logo5" android:duration="210" />
<item android:drawable="@drawable/logo6" android:duration="210" />
<item android:drawable="@drawable/logofinal" android:duration="210" />
</animation-list>

Step 2- Create an activity_main.xml file

It Includes : An Image View

<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" >

    <ImageView
        android:id="@+id/imageAnimation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true" />

</RelativeLayout>

Step 3- Outside the onCreate method :

Declare the Image View and Animation Drawable

// Declaring an Image View and an Animation Drawable

ImageView view;
AnimationDrawable frameAnimation;

Step4- Inside the OnCreate method:

Typecast the Image view Typecast the Animation Drawable Set the drawable backgroung on the image view

// Typecasting the Image View
view = (ImageView) findViewById(R.id.imageAnimation);

// Setting animation_list.xml as the background of the image view
view.setBackgroundResource(R.drawable.animation_list);

// Typecasting the Animation Drawable
frameAnimation = (AnimationDrawable) view.getBackground();

Step5- After the onCreate method :

The animation should only run when it is in focus that is when it is visible to the user. Hence define this method after the onCreate method.

// Called when Activity becomes visible or invisible to the user
@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
      if (hasFocus) {
    // Starting the animation when in Focus
    frameAnimation.start();
    } else {
        // Stoping the animation when not in Focus
    frameAnimation.stop();
      }
}

Source

Community
  • 1
  • 1
Praful Bhatnagar
  • 7,425
  • 2
  • 36
  • 44
2

i would do this the following way:

  • create a custom view which contains a bitmap and in onDraw() this bitmap is drawn on the canvas
  • give this custom view a setter, to give it a new bitmap (maybe as a ressouce-id or something similar)
  • create a new Thread (with a UI-Handler) which changes the resource of the canvas at least 24times per second and calls customView.invalidate() via handler.post

this worked for me

edit: the code

Activity:

package de.test.animation;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class AnimationTestActivity extends Activity {
Button btn;
CustomView customView;
LinearLayout layout;

int[] imageIDs;

private void init(){    //array with my ressouce-IDs
    imageIDs = new int[]{
        R.drawable.pic1,    
        R.drawable.pic2,    
        R.drawable.pic3,    
        R.drawable.pic4,    
        R.drawable.pic5,    
        R.drawable.pic6,    
        R.drawable.pic7,    
        R.drawable.pic8,    
        R.drawable.pic9,    
        R.drawable.pic10,   
        R.drawable.pic11,   
        R.drawable.pic12,   
        R.drawable.pic13,   
        R.drawable.pic14,   
        R.drawable.pic15,   
        R.drawable.pic16,   
        R.drawable.pic17,   
        R.drawable.pic18,   
        R.drawable.pic19,   
        R.drawable.pic20,   
        R.drawable.pic21,   
        R.drawable.pic22,   
        R.drawable.pic23,   
        R.drawable.pic24    
    };
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    init();

    btn = (Button) findViewById(R.id.btnStart);
    layout = (LinearLayout)findViewById(R.id.layout);

    customView = new CustomView(this);
    customView.setNewImage(imageIDs[0]);
    layout.addView(customView);

    btn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Thread t = new Thread(){
                private final int FPS = 24; //How many frames will be dran per second
                private final int SLEEPTIME = 1000/FPS; //Time, the thread waits, before drawing the next picture

                @Override
                public void run() {
                    super.run();
                    for(int i=0;i<imageIDs.length;i++){
                        customView.setNewImage(imageIDs[i]);    //set next picture
                        customView.repaint();   //draw the picture on the canvas
                        try {
                            sleep(SLEEPTIME);   //wait, until the next picture can be drawn
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            t.start();
        }
    });
}
}

CustomView:

package de.test.animation;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;


public class CustomView extends View {
private Bitmap image;   //image to be drawn on this view
private Context context;

public CustomView(Context context) {    //constructor
    super(context);
    this.context = context;
}

public void setNewImage(int r_id){  //method to set a new picture (via resouce-id)
    image = BitmapFactory.decodeResource(context.getResources(), r_id); //decode the image from the resouces
}

public void repaint(){  //method to repaint this view
    this.post(new Runnable(){   //posting via a new runnable (otherwhise you get a "calledByWrongThreadException"
        @Override
        public void run() {
            invalidate();   //Thread initiates UI-Thread to update this view
        }
    });
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawBitmap(image, 0, 0, new Paint()); //draw the picture in the view
}


}

I hope this helps you. Good luck then.

Tom Mekken
  • 1,019
  • 1
  • 12
  • 27