android animation is not finished in onAnimationEnd

Solution 1:

Here is the actual bug related to this issue http://code.google.com/p/android-misc-widgets/issues/detail?id=8

This basically states that the onAnimationEnd method doesn't really work well when an AnimationListener is attached to an Animation

The workaround is to listen for the animation events in the view to which you were applying the animation to For example if initially you were attaching the animation listener to the animation like this

mAnimation.setAnimationListener(new AnimationListener() {
    @Override
    public void onAnimationEnd(Animation arg0) {
        //Functionality here
    }
});

and then applying to the animation to a ImageView like this

mImageView.startAnimation(mAnimation);

To work around this issue, you must now create a custom ImageView

public class MyImageView extends ImageView {

and then override the onAnimationEnd method of the View class and provide all the functionality there

@Override
protected void onAnimationEnd() {
    super.onAnimationEnd();
    //Functionality here
}

This is the proper workaround for this issue, provide the functionality in the over-riden View -> onAnimationEnd method as opposed to the onAnimationEnd method of the AnimationListener attached to the Animation.

This works properly and there is no longer any flicker towards the end of the animation. Hope this helps.

Solution 2:

I was abe to resolve this by calling clearAnimation() on the view being animated inside onAnimationEnd, that took away the flicker Its weird why would anyone have to do that, as onAnimationEnd callback should have been called only if the animation has already ended. But I guess the answer lies in the depth of Framework on how view/layout handles animation callback. For now take it as a hack-free solution, that just works.

        animation.setAnimationListener(new AnimationListener() {

        public void onAnimationEnd(Animation anim) {
            innerView.clearAnimation();   // to get rid of flicker at end of animation

            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams
            (innerBlockContainer.getWidth(), innerBlockContainer.getHeight());

            /* Update lp margin, left/top to update layout after end of Translation */
            ViewGroup parent_ofInnerView = (ViewGroup)innerView.getParent();
            vp.updateViewLayout(innerBlockContainer, lp);

        }

        public void onAnimationRepeat(Animation arg0) {}

        public void onAnimationStart(Animation arg0) {
        }

    });

     innerView.startAnimation(animation);

Solution 3:

I had a similar problem and I used Soham's solution with custom view class.

It worked fine, but at the end, I've found a simpler solution that worked for me.

After calling the view.StartAnimation(animation), and before the next step in my program, I've added a short delay that will be long enough to let the animation finish, but short enough to be unnoticeable by the user:

new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
           nextStepInMyProgram();
       }
     }, 200);// delay in milliseconds (200)