让Android AnimatorSet停止动画

6

我有以下的AnimatorSet方法:

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;
}

这个变量名为throbber,它会被设置,并且偶尔会被这个方法更新:

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

但我无法停止它的动画,以下是当前尝试停止动画的方法:
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();
}

我无法停止它的动画。更新:我刚刚尝试了将各个对象动画器的本地引用存储起来,然后在每个动画器上调用setRepeatCount、mode、pause、end、cancel,但仍然没有效果。


请确保下次格式化/缩进您的代码。如果您这样做,您将获得更多的答案……在我整理之前,它很难阅读。 - Alex Lockwood
此外,在这里调用 clearAnimation 方法将完全没有任何效果。该方法清除了视图的 Animation,这是一个与对象 Animator 完全不同的概念。 - Alex Lockwood
还有,你的代码中有一个错别字:pulseX.setRepeatMode(ObjectAnimator.);。你能修复一下吗? - Alex Lockwood
谢谢Alex。你有实际的答案吗? - wkhatch
我解决了这个问题,不再使用无限的repeatCount,而是通过一些计算来确定重复次数。尽管如此,它仍然很让人恼火,因为无论如何都无法取消/停止。 - wkhatch
任何设置了repeatCount为无限的对象动画器或动画器集合都不会停止,除非你离开视图。 - wkhatch
2个回答

30

dialCenterImageView.clearAnimation();

这将不会影响ObjectAnimator创建的动画。您只能清除通过startAnimation()在视图上启动的动画。

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

任何重复次数设置为无限的对象动画器或动画器集都不会停止,除非您离开视图。

确实如此!我今天吃了大亏才知道这一点。所以我想补充一下。您需要存储ObjectAnimator实例的引用,并稍后调用cancel()来取消它。

我在旋转安卓手机屏幕时遇到了这个问题,在这种情况下,您的活动基本上是使用新布局重新创建的。

所以这就是我做的。

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

你也可以在onPause()方法中完成它。

另一个要注意的重要点。 如果你在你的ObjectAnimator实例上调用了start() n次,那么你需要调用cancel()n次才能完全停止动画。

另外,如果你添加了AnimatorSet监听器,请确保在调用取消之前已经删除了这些监听器。

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

1
非常棒的东西,Aniket;谢谢。看起来可能是因为我没有先移除监听器,所以我的取消调用没有起作用。如果我有时间,出于好奇,我会回到这个时间点,看看是否有效。再次感谢! - wkhatch

4
这里回复晚了,但是我做的事情(不得不说没有谷歌的完整性),是将视图的ObjectAnimator实例传递给它的标签中,需要知道这个实例才能停止它。
例如,在视图上启动/取消无限旋转...
private void rotateStart(View view) {
    ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);
    // set animator instance as view's tag
    view.setTag(animator); 
    animator.setDuration(800);
    animator.setRepeatMode(ObjectAnimator.RESTART);
    animator.setRepeatCount(ObjectAnimator.INFINITE);
    animator.start();
}

private void rotateCancel(View view) {
    // get view's tag, which is its animator instance
    ObjectAnimator animator = (ObjectAnimator) view.getTag();
    if (animator != null) {
        animator.cancel();
    }
}

我认为这个可以胜任,无论是单个动画还是一组动画。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接