I have an ImageView that is being used to show some frame animation.
The Duration for these images are all set to 100.
However, the ImageView needs to be hidden sometimes. So the animation is stopped and the ImageView is set to GONE.
When it's time to show the ImageView again, its visibility is set to VISIBLE and the animation is started.
HOWEVER - now the animation is really fast; instead of a duration of 100, it looks like 50. But when I check the duration it still says 100 - but it definitely doesn't look like it.
The code to hide and show the ImageView is as follows:
//hide the animation
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
if (frameAnim.isRunning() == true)
{
frameAnim.stop();
}
frameAnim.setVisible(false, false);
animImgView.setVisibility(View.GONE);
//show animation
animImgView.setVisibility(View.VISIBLE);
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
frameAnim.setVisible(true, true);
frameAnim.start();
What could be the trouble ?
After some experimentation I found that the best way is to simply implement:
//hide the animation
animImgView.setVisibility(View.GONE);
//show animation
animImgView.setVisibility(View.VISIBLE);
this will preserve the animation speed. My original intent with the animation stop/start was to ensure the CPU wasn't doing more than was needed.
To achieve the original goal of not just changing visibility, but also stopping the animation when invisible:
//hide the animation
animImgView.setVisibility(View.GONE);
//stop animation
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
if (frameAnim.isRunning() == true)
{
frameAnim.stop();
}
frameAnim.setVisible(false, false);
//start animation
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
frameAnim.setVisible(true, true);
frameAnim.start();
//show animation
animImgView.setVisibility(View.VISIBLE);
The difference here is that starting and stopping the animation occurs while the ImageView is invisible/gone. For some reason, starting and stopping the animation when it is visible causes the timing issues.
Source: I ran into this problem myself and fixed it using this technique.
Struggling with Android I found next solution:
don't use start() and stop() methods.
Use setVisible(true, true) to start animation:
animImgView.setVisibility(View.VISIBLE);
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
frameAnim.setVisible(true, true);
and setVisible(false, true) to stop it (note the bold true):
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
frameAnim.setVisible(false, true);
animImgView.setVisibility(View.GONE);
Related
I have implemented image rotate animation on the audio player screen where when audio start than image rotation and when a user clicks on pause button animation stop, I use clearAnimation() method for stopping animation and when user resume I call startAnimation() method but this Look bad because when I clear animation image degree like 90 was different and when I startAnimation() again its starting point was 0. please check this video where animation having an issue while play/pause audio Watch This Video.
So I find a pause()/resume() animation for better smoothness. Can anyone help me to sort out animation smoothness or working batter?
Use Animator object to animate the view's property (like android:rotation):
View imgView = findViewById(R.id.image);
View playPauseBtn = findViewById(R.id.button);
final ObjectAnimator anim = ObjectAnimator.ofFloat(imgView, View.ROTATION, 0f, 90f)
.setDuration(4000);
anim.setRepeatCount(Animation.INFINITE);
anim.setInterpolator(new LinearInterpolator());
anim.start();
playPauseBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (anim.isPaused()) {
anim.resume();
} else {
anim.pause();
}
}
});
I have created an object of AnimationDrawable with Bitmap frames.
Next what I want to do is, to perform a function every time the Frame changes in that Animation. But I have no idea how I will be able to achieve this.
Is there any inbuilt or custom method available through which we can get triggered for frame change? Please help!
To create and start the Animation, I have used code as below:
int duration = 200;
Animation myAnim = new AnimationDrawable();
for (Bitmap frame : framesList) {
myAnim.addFrame(new BitmapDrawable(frame), duration);
}
if (android.os.Build.VERSION.SDK_INT <=
android.os.Build.VERSION_CODES.JELLY_BEAN)
imgPicture.setBackgroundDrawable(myAnim);
else
imgPicture.setBackground(myAnim);
myAnim.start();
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.
I have a frame-by-frame animation and I want to set a specific frame when the stop method has been called. I searched a lot but I haven't found what I was serching for.
Does this method exists? Is it possible to do that?
Use this method on your AnimationDrawable: animationDrawable.selectDrawable(index)
Assuming that frame-by-frame means AnimationDrawable given in the background of an ImageView.
Like that (or via xml):
AnimationDrawable animationDrawable = new AnimationDrawable();
animationDrawable.addFrame(drawableFrame1, 0);
animationDrawable.addFrame(drawableFrame2, 1);
animationDrawable.addFrame(drawableFrame3, 2);
animationDrawable.addFrame(drawableFrame4, 3);
iv = new ImageView(this);
iv.setBackgroundDrawable(animationDrawable);
Here is the code to retrieve a given frame and set it to the background of the ImageView
onStop() {
Drawable drawableFrame2 = ((AnimationDrawable)iv.getBackground()).getFrame(2);
iv.setBackgroundDrawable(drawableFrame2);
iv.postInvalidate();
}