Making Android AnimatorSet stop animating

wkhatch picture wkhatch · Aug 12, 2014 · Viewed 9.4k times · Source

I have the following AnimatorSet method:

private AnimatorSet dialCenterThrob() {
    int bpm = workoutStream.getHeartRate();
    dialCenterImageView.clearAnimation();
    AnimatorSet finalSet = new AnimatorSet();

    ObjectAnimator pulseX = ObjectAnimator.ofFloat(dialCenterImageView, View.SCALE_X, 0.98f, 1.06f);
    ObjectAnimator pulseY = ObjectAnimator.ofFloat(dialCenterImageView, View.SCALE_Y, 0.98f, 1.06f);

    pulseX.setRepeatMode(ObjectAnimator.REVERSE);
    pulseX.setRepeatCount(ObjectAnimator.INFINITE);
    pulseY.setRepeatMode(ObjectAnimator.REVERSE);
    pulseY.setRepeatCount(ObjectAnimator.INFINITE);
    pulseX.setDuration(bpm);
    pulseY.setDuration(bpm);
    pulseX.setInterpolator(new AccelerateInterpolator());
    pulseY.setInterpolator(new AccelerateInterpolator());

    finalSet.playTogether(pulseX, pulseY);

    return finalSet;
}

This is set on a var, called throbber, and is occasionally updated by this method:

private void updateThrobbing() {
    if (hasThrob()) {
        throbber = dialCenterThrob();
        throbber.start();
    } else {
        if (throbber != null && throbber.isRunning()) {
            stopThrobbing();
        }
    }
}

But I cannot get it to stop animating, and here's the method that currently attempts to do so:

public void stopThrobbing() {
    List<Animator> throbbers = throbber.getChildAnimations();
    for(Animator animator : throbbers) {
        //accomplishes nothing
        ((ObjectAnimator)animator).setRepeatCount(0);
        ((ObjectAnimator)animator).setRepeatMode(0);
    }

    throbber.pause(); //nothing
    throbber.cancel(); //and again, nothing
    throbber.end();//shocking, I know, but really, nothing
    throbber = null;//you'd think this would definitely do it, but no
    //desparate attempt, in vein, of course
    dialCenterImageView.clearAnimation();
}

I cannot get it to stop animating. Update: I just tried storing local ref's to the individual object animators, and then calling setRepeatCount, mode, pause, end, cancel on each one, and still nothing.

Answer

Aniket Thakur picture Aniket Thakur · May 13, 2015

dialCenterImageView.clearAnimation();

This will have no affect on animations created by ObjectAnimator. You can only clear animation which you have started on the view by startAnimation()

findViewById(R.id.yourViewId).startAnimation(yourAnimation);
findViewById(R.id.yourViewId).clearAnimation();

any object animator, or animatorset with repeatCount set to Infinite will NOT stop, no matter what you do, short of leaving the view.

True that! Learned this today the hard way. So will add my two cents. You need to store the reference of the ObjectAnimator instance and later call cancel() on it.

I encountered this when animation was still continuing after rotating your android phone screen in which case your activity is essentially re created with new layout.

So this is what I did

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    ObjectAnimator buttonOneObjectAnimator = myOnClickListener.getButtonOneColorAnim();
    if(buttonOneObjectAnimator != null)
        buttonOneObjectAnimator.cancel();
}

You can very well do it in onPause() as well.

Another important point to note. If you call start() on your ObjectAnimator instance n times then you will have to call cancel() n times for animation to completely stop.

Also if you have AnimatorSet listeners added , then make sure you have removed the listeners before calling cancel.

yourAnimatorSet.removeAllListeners();
yourAnimatorSet.end();
yourAnimatorSet.cancel();