I have a basic question about starting a frame-by-frame animation.
When I call the AnimationDrawable.start() method from my code directly, it doesn't seem to work.
public void onCreate(Bundle savedInstanceState) {
...
mAnimation.start();
...
}
But if I put this line inside the onClick() callback method of a button, pressing the buton starts the animation.
Why doesn't this line work in the code?
Thanks!
Code:
public class MyAnimation extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
AnimationDrawable mframeAnimation = null;
super.onCreate(savedInstanceState);
setContentView(R.layout.my_animation);
ImageView img = (ImageView) findViewById(R.id.imgMain);
BitmapDrawable frame1 = (BitmapDrawable) getResources().getDrawable(
R.drawable.splash1);
BitmapDrawable frame2 = (BitmapDrawable) getResources().getDrawable(
R.drawable.splash2);
int reasonableDuration = 250;
mframeAnimation = new AnimationDrawable();
mframeAnimation.setOneShot(false);
mframeAnimation.addFrame(frame1, reasonableDuration);
mframeAnimation.addFrame(frame2, reasonableDuration);
img.setBackgroundDrawable(mframeAnimation);
mframeAnimation.setVisible(true, true);
//If this line is inside onClick(...) method of a button, animation works!!
mframeAnimation.start();
}
}
It's important to note that the start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. If you want to play the animation immediately, without requiring interaction, then you might want to call it from the onWindowFocusChanged() method in your Activity, which will get called when Android brings your window into focus.
Very end of the page
http://developer.android.com/guide/topics/graphics/2d-graphics.html
ImageView img = (ImageView)findViewById(R.id.some layout);
AnimationDrawable frameAnimation = (AnimationDrawable)img.getDrawable();
frameAnimation.setCallback(img);
frameAnimation.setVisible(true, true);
frameAnimation.start();
and to add animation you can do something like
<animation-list android:id="#+id/my_animation" android:oneshot="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/frame1" android:duration="150" />
<item android:drawable="#drawable/frame2" android:duration="150" />
</animation-list>
Use a Runnable to insert the start() message to message queue, just add this LOC to replace your mFrameAnimation.start();
img.post(new Starter());
Helper inner class:
class Starter implements Runnable {
public void run() {
mFrameAnimation.start();
}
}
to play an animation just in onCreate(...) add:
ImageView mImageView=(ImageView) findViewById(R.id.image);
mImageView.setBackgroundResource(R.anim.film);
mFrameAnimation = (AnimationDrawable) mImageView.getBackground();
mImageView.post(new Runnable(){
public void run(){
mFrameAnimation.start();
}
});
Related
I am trying to change repeatedly images in image view (it doesn't matter what component to use). I need to change background image each N seconds.
I have tried to use Animation drawable declaring images in xml file.
It works, but I don't know to apply any effect to it, like fade in,blur or something other.
So my task is to change periodically background image with transition effect.
Please suggest how to deal with this problem, I would be very grateful for any help.
I used an image switcher to switch images in regular intervals
xml part
<ImageSwitcher
android:id="#+id/smsimg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/defaultimage" />
class code was like this
private final int[] images = { R.drawable.vava, R.drawable.vavaone,R.drawable.vavatwo,R.drawable.vavathree,R.drawable.vavafour,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
img=(ImageSwitcher)findViewById(R.id.smsimg);
startAnimatedBackground();
private void startAnimatedBackground() {
Animation aniIn = AnimationUtils.loadAnimation(this,
android.R.anim.fade_in);
aniIn.setDuration(3000);
Animation aniOut = AnimationUtils.loadAnimation(this,
android.R.anim.fade_out);
aniOut.setDuration(3000);
final ImageSwitcher imageSwitcher = (ImageSwitcher) findViewById(R.id.smsimg);
imageSwitcher.setInAnimation(aniIn);
imageSwitcher.setOutAnimation(aniOut);
imageSwitcher.setFactory(this);
imageSwitcher.setImageResource(images[index]);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
if (isRunning) {
index++;
index = index % images.length;
Log.d("Intro Screen", "Change Image " + index);
imageSwitcher.setImageResource(images[index]);
handler.postDelayed(this, interval);
}
}
};
handler.postDelayed(runnable, interval);
}
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.
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.
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
I would like to animate some images.
Could someone tell me why this first piece of code does not work, but the second one does work ?
And if I have to use the second one, how do I STOP the animation into the runnable ?
EDIT : the first code works on android 4.x, but not on 2.2 (both simulator and device)
code 1 (into "onCreate()" ):
ImageView boule = (ImageView)findViewById(R.id.boule);
boule.setImageBitmap(null);
boule.setBackgroundResource(R.anim.anime);
AnimationDrawable animation = (AnimationDrawable)boule.getBackground();
animation.start();
// does not animate anything...
code 2 (also into "onCreate()" ) :
ImageView boule = (ImageView)findViewById(R.id.boule);
boule.setImageBitmap(null);
boule.setBackgroundResource( R.anim.anime );
final AnimationDrawable animation = (AnimationDrawable) boule.getBackground();
boule.post(new Runnable() {
public void run() {
if ( animation != null ) animation.start();
}
});
// OK, it works, but how do I stop this ?
You can try this.. this code works properly
BitmapDrawable frame1 = (BitmapDrawable)getResources().getDrawable(R.drawable.jth);
BitmapDrawable frame2 = (BitmapDrawable)getResources().getDrawable(R.drawable.jthj);
int duration = 10;
final AnimationDrawable ad = new AnimationDrawable();
ad.setOneShot(false);
ad.addFrame(frame1, duration);
ad.addFrame(frame2, duration);
iv.setBackgroundDrawable(ad);
ad.setVisible(true, true);
Put ad.start(); in button onClickListener and ad.stop(); for stop animantion
I'm trying to show two different animations. It works fine with the first one. But when I stop the first animation and call setBackgroundResource() second time with my second animation ( and then call start() ) it shows only the first frame.
Is it possible to call setBackgroundResource() twice to set different animations?
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
ImageView imgView= (ImageView) findViewById(R.id.imgView);
imgView.setBackgroundResource(R.anim.animation1);
AnimationDrawable frameAnimation = (AnimationDrawable) imgView
.getBackground();
frameAnimation.setCallback(imgView);
frameAnimation.start();
//Schedule the timer
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
showAnimation2();
}
}, 20000);
}//if hasFocus
}
/**
* Show second animation
*/
public void showAnimation2(){
ImageView imgView= (ImageView) findViewById(R.id.imgView);
AnimationDrawable frameAnimation = (AnimationDrawable) imgView
.getBackground();
// stop first animation
frameAnimation.stop();
imgView.setBackgroundResource(R.anim.animation2);
frameAnimation.setCallback(imgView);
//start second animation
frameAnimation.start();
// here I see the first frame of second animation only
}
I also tried to play with setVisible(...) but it doesn't help
I solved this problem by using two ImageView and switching between them. I use setVisibility() method to hide one view with the first animation and show the second view.
In my android project I have an image that i want to rotate it and create animation for long time.
I can run program and it works fine. but I don't know how can I stop it. if you know please tell me.
Thanks
This is my code, I have a menu with two items, When I click on Start item, startAnimation function runs and when I click on Stop item, stopAnimation runs.:
public class Hypnagogic extends Activity
{
ImageView imView;
Animation an;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imView = (ImageView)findViewById(R.id.imView);
}
private void startAnimation()
{
an = AnimationUtils.loadAnimation(this, R.anim.spin);
imView.startAnimation(an);
}
private void stopAnimation()
{
;//there is no any stop function!
}
}
also, in res/anim I put spin.xml that is my animation
<?xml version="1.0" encoding="utf-8"?>
<set>
<rotate
android:fromDegrees="0"
android:toDegrees="-18000"
android:pivotX="50%"
android:pivotY="50%"
android:duration="50000" />
</set>
EDIT: I see. Okay, try the clearAnimation() method associated with the View class. You can call it directly on your ImageView, I'm almost certain this should work for your case:
imView.clearAnimation();
What have you tried? AnimationDrawable has a stop() method. You need to post how you're creating/starting the animation.