How to get "AnimationDrawable" event - android

I am working on game application and i use AnimationDrawable for image change.
but problem is i want imageview invisible when Animation is finish.so what should i do
for this.
My code is like this...
mAnimation = new AnimationDrawable();
mAnimation.addFrame(getResources().getDrawable(R.drawable.d5),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d4),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d3),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d2),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d1),150);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d2),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d3),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d4),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d5),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.new_transparent),50);
mAnimation.setOneShot(true);
mDogImage.setImageDrawable(mAnimation);
Thanks in advance.

There is no event or listener that will notify you.You just need to apply the trick
Use mAnimation.getNumberOfFrames(); to get total number of frames and since each frame will last long for 50ms.So your animation is supposed to end in mAnimation.getNumberOfFrames() * 50 ms.
For eg if you have 9 frames and each frame has duration of 50ms then your animation is going to end in 450ms.
So conclusion will be you will make your ImageView invisible after 450ms once animation starts.

Related

How to resume and pause ObjectAnimator in Android for API Levels below 19?

I am aware that API level 19 supports pause() and resume() on ObjectAnimators. But in my project at API level 14, I have an ObjectAnimator which is applied to an Image view to rotate it. I want to pause the animation provided by the ObjectAnimator on touch and resume it from the place where the image view was (before touch down).
So I attempted to save the current play time and cancel the object animator on my stopAnimation() function.
private void stopAnimation(){
currentTime = mGlobeAnimator.getCurrentPlayTime();
mGlobeAnimator.cancel();
}
In the startAnimation() function, I recreate the animator, set its target to the image view, set the saved play time and start it.
private void startAnimation(Context context, View view, float startAngle) {
ObjectAnimator globeAnimatorClone = (ObjectAnimator)AnimatorInflater.loadAnimator(context, R.animator.rotate_globe);
globeAnimatorClone.setTarget(mImageView);
globeAnimatorClone.setCurrentPlayTime(currentTime);
globeAnimatorClone.start();
}
This does not work. Would anybody help please with any pointers to pause and resume animation provided by animator for API level before 19?
I think I got it working by starting the animator and then setting the currentPlayTime(). The documentation clearly tells (which I just stumbled upon) that if the animation has not been started, the currentPlayTime set using this method will not advance the forward!
Sets the position of the animation to the specified point in time. This time should be between 0 and the total duration of the animation, including any repetition. If the animation has not yet been started, then it will not advance forward after it is set to this time; it will simply set the time to this value and perform any appropriate actions based on that time. If the animation is already running, then setCurrentPlayTime() will set the current playing time to this value and continue playing from that point. http://developer.android.com/reference/android/animation/ValueAnimator.html#setCurrentPlayTime(long)
private void stopAnimation(){
mCurrentPlayTime = mRotateAntiClockwiseAnimator.getCurrentPlayTime();
mRotateAntiClockwiseAnimator.cancel();
}
private void startAnimation() {
mRotateAntiClockwiseAnimator.start();
mRotateAntiClockwiseAnimator.setCurrentPlayTime(mCurrentPlayTime);
}
What you are doing is that it will just restart your animation, instead you can create a custom class for animation with pause and resume method.
You need to first check if the device is 19 api and above if it is then use the native pauses and resume of the object animator else use the regular Animation designed from api 1, you can follow this thread for pause and resume below api 19.
Its probably too late for me to answer, i just came across this problem and i solved it using your method.
i just added two things to your approach
1. In the start of animation check if the ** mCurrentPlayTime** is greater than zero.if its >0 then setCurrentPlayTime. otherwise its useless.
2. when your animation ends make it zero again.

Using animation set, animation does not happen sequentially

I am trying to set blink animation on two words so that they blink one after the other, but what ever I do only 2nd word is displayed, can any one provide me method for doing the same, I am working with API level 10 so, cannot use "Animatorset".
AnimationSet set = new AnimationSet( true );
Animation blink = new AlphaAnimation(1, 0 );
blink.setDuration(duration);
blink.setFillAfter(true);
set.addAnimation( blink );
txtvw.setText("FIRST");
txtvw.setVisibility(View.VISIBLE);
txtvw.setAnimation(blink);
AnimationSet set2 = new AnimationSet( true );
Animation blink2 = new AlphaAnimation(1, 0 );
blink2.setDuration(duration);
blink2.setFillAfter(true);
set2.addAnimation( blink );
txtvw.setText("SECOND");
txtvw.setVisibility(View.VISIBLE);
txtvw.setAnimation(blink2);
if your code is like this, your text "first" gets replaced by text "Second" immediately. And the animation is shown. This animation gives an illusion that only second is blinking. Your text first is being set for microseconds but it immediately gets replaced by second.
If you want to show both the texts, you may need to use Thread
Using two animation sets for the same animations (that is, "blinking animation") is an overkill. You may just repeat your animation 2 times. Use setRepeatCount(int) in conjunction with setRepeatMode(int) to achieve this.
If you insist on using the code you have provided in your post, you will need to specify animation offset. Animation offset indicates "how much time should animation wait before start". For example, if you have Animation a and b, and want b happen after a, you might use the code:
b.setStartOffset(a.getDuration());
Then b animation will happen just after a has finished.

how start frame animations in android?

I want to start 5 different frame animations:One for cap,one for scarf
one for character,one fro face Expressions and one for scarf borders.I want it to look like man is running with scarf hat.Animations started fine,
but all animations are not playing at same time.
Please help me to do that.
I set the png images through addFrame method in my code .
I am posting the sample code here
capanimation.setVisible(true,true);
capanimation.start();
Log.i("fani"," cap: "+System.currentTimeMillis() );
scarfmainanimaiton.setVisible(true,true);
scarfmainanimaiton.start();
Log.i("fani"," sca: "+System.currentTimeMillis() );
faceexpressionanimation.setVisible(true,true);
faceexpressionanimation.start();
Log.i("fani"," fac: "+System.currentTimeMillis() );
charecteranimation.setVisible(true,true);
charecteranimation.start();
Log.i("fani"," cha: "+System.currentTimeMillis() );
I think you can do this using frame by frame animation which is very easy. I will provide link for that check http://developer.android.com/guide/topics/graphics/drawable-animation.html
In that you can put your images in resources folder and that can animated as per requirement. Hope this will help you.
In may app i am giving choice to user to select cap,scarf among different options
based on the user selection i need to animate that cahrecter with user selcted cap and scarf
//Iam posting the some sample code here
public int maledance[]={R.drawable.char01,R.drawable.char02,R.drawable.char03,R.drawable.char04,R.drawable.char05,R.drawable.char06
,R.drawable.char07,R.drawable.char08,R.drawable.char09,R.drawable.char10,R.drawable.char11,R.drawable.char12,R.drawable.char13,R.drawable.char14,R.drawable.char15};
public int maledancescarf1[]={R.drawable.scarve101,R.drawable.scarve102,R.drawable.scarve103,R.drawable.scarve104,R.drawable.scarve105,R.drawable.scarve106,
R.drawable.scarve107,R.drawable.scarve108,R.drawable.scarve109,R.drawable.scarve110,R.drawable.scarve111,R.drawable.scarve112,R.drawable.scarve113,R.drawable.scarve114,R.drawable.scarve115};
etc......
charecteranimation=new AnimationDrawable();
capanimation=new AnimationDrawable();
capboarderanimation=new AnimationDrawable();
scarfmainanimaiton=new AnimationDrawable();
scarfboarderanimation=new AnimationDrawable();
faceexpressionanimation=new AnimationDrawable();
for(int i=0;i<maledance.length;i++)
{
Log.i("fani","string lenth is "+maledance.length+" delay is "+delay);
charecteranimation.addFrame(getResources().getDrawable(maledance[i]),t);
capanimation.addFrame(getResources().getDrawable(maledancecap[i]),t);
scarfmainanimaiton.addFrame(getResources().getDrawable(maledancescarf[i]),t);
faceexpressionanimation.addFrame(getResources().getDrawable(malefaceexpression[i]),t);
}
capanimation.setOneShot(false);
charecteranimation.setOneShot(false);
scarfmainanimaiton.setOneShot(false);
faceexpressionanimation.setOneShot(false);
//in onwindowfocuschanged listner i am starting the animations

How to reset AnimationDrawable

I have to animate a circular count down timer and I'm doing it by animating the background of an ImageView using AnimationDrawable (each image has the according slice of the circle removed). The problem is that the user has the ability to pause this animation, so I have to reload the animation but then a problem appears. I've tried setting the the animation to null, setting the background of the ImageView to null, setting the visibility of the animation, but practically nothing helped, because number of frames remains the same. I have to find a workaround for deleting all frames and adding new ones or to reset the whole animation to the default state.
Step 1 - initializing the animation (starting frame index is 0)
timerView.setBackgroundResource(R.drawable.timer_switch);
timerAnimation = (AnimationDrawable)timerView.getBackground();
System.out.println("Number of frames: " + timerAnimation.getNumberOfFrames());
for (int frameIndex = startingFrameIndex; frameIndex < 60; frameIndex++) {
if (frameIndex < 10) {
uri = "drawable/timer_0000" + frameIndex;
} else {
uri = "drawable/timer_000" + frameIndex;
}
imageResourceId = getResources().getIdentifier(uri, null, getPackageName());
timerAnimation.addFrame(getResources().getDrawable(imageResourceId), timerImageFrameDuration);
}
Step 2 - here's the tricky part where I don't know what to do. Things that I've tried:
timerAnimation.stop();
timerAnimation.setCallback(null);
timerAnimation.setVisibility(true, false);
timerAnimation = null;
Step 3 - after calling step 2 I call step 1 again, but the Sys.out still displays 60 as the current number of frames. (starting index here is set to the last hidden frame when pause button was tapped.)
Any idea is welcomed.
Thanks
This will send the (AnimationDrawable) timerAnimation to the first frame as soon as stop() has been called:
timerAnimation.stop();
timerAnimation.selectDrawable(0);
I had the same problem where stopping the animation would stop on the current frame. I wanted it to behave like iOS, where stopping would go back to the first frame. This solution works for me:
((AnimationDrawable)(someButton.getBackground())).stop();
someButton.setBackgroundDrawable(null);
someButton.setBackgroundResource(R.drawable.animation);
This first stops it (probably not necessary). Then it kills the background animation. Finally, it recreates the background.
Another possible solution would be to have the same image for the first frame and last frame and do the following instead of calling the stop() method.
((AnimationDrawable)(someButton.getBackground())).setOneShot(true);
if anyone does look into this any further. There is also a method called setVisible(boolean visible, boolean restart). However, that did not work for myself.
You can try public boolean setVisible (boolean visible, boolean restart) and it will play the animation once. For example:
animationDrawable.setVisible(false, true);
I would setVisibility(true, true):
timerAnimation.stop();
timerAnimation.setVisibility(true, true);
visible boolean: true if visible, false otherwise
restart boolean:
when visible, true to force the animation to restart from the first frame
android.view.animation.Animation.reset() doesnt work?

Animation Drawable does not animate in android?

I have created an animation drawable and image view in my main game thread which is configured from the activity that handles the game thread (starting it etc.). My code in this handling activity looks like this:
mDistractionsThread.animation.addFrame(getResources().getDrawable(R.drawable.one), 1000);
mDistractionsThread.animation.addFrame(getResources().getDrawable(R.drawable.two), 1000);
mDistractionsThread.animation.addFrame(getResources().getDrawable(R.drawable.three), 1000);
mDistractionsThread.animation.setOneShot(false);
mDistractionsThread.imageAnim =(ImageView) findViewById(R.id.img);
mDistractionsThread.imageAnim.setBackgroundDrawable(mDistractionsThread.animation);
mDistractionsThread.animation.start();
And as you can see the variable mDistractionsThread is a handle to the thread itself. This compiles fine but only displays the first frame (R.drawable.one) and does not animate at all. What is it I have missed?
I tried to set animation.start() from run() within mDistractionsThread but that just gave me an fatal exception because the View can only be altered from the class that alters its fields - which in this case is not the game thread.
How can I resolve this and get it animating through the frames, and for bonus points, moving across the x-axis?!
Many thanks
It matters where you start the animation. Try starting it in onFocusChanged() in the activity. It should help

Categories

Resources