如何重复一个属性动画?

11

我正在制作一个屏幕上的气泡动画,但是动画时间结束后气泡停止了。我该如何重复播放动画或使其无限循环?

bub.animate();
bub.animate().x(x2).y(y2);
bub.animate().setDuration(animationTime);       
bub.animate().setListener(new AnimatorListenerAdapter() {

    @Override
    public void onAnimationStart(Animator animation) {
        animators.add(animation); 
    } 

    @Override
    public void onAnimationRepeat(Animator animation) {
    }

    @Override
    public void onAnimationEnd(Animator animation) {
    }
});

您还可以使用支持重复的ValueAnimator,请参阅https://developer.android.com/reference/android/animation/ValueAnimator.html - user8389458
6个回答

16

由于ViewPropertyAnimator仅适用于简单动画,因此请使用更高级的ObjectAnimator类 - 基本上是方法setRepeatCount和另外的setRepeatMode


1
是的,ViewPropertyAnimator 用于简单动画,对于更复杂的用法,请尝试使用 ObjectAnimator。抱歉回答不够清晰。 - asylume
@asylume 根据这里的十几个主题,仍然没有一个好的方法来重复由两个ObjectAnimator组成的AnimatorSet。如果我错过了什么,请告诉我。 - ivan8m8

9

你可以使用 CycleInterpolator。例如,像这样:

    int durationMs = 60000;
    int cycleDurationMs = 1000;
    view.setAlpha(0f);
    view.animate().alpha(1f)
            .setInterpolator(new CycleInterpolator(durationMs / cycleDurationMs))
            .setDuration(durationMs)
            .start();

4
你怎么让它无限循环播放? - android developer

8

这里是一个Kotlin的例子,使用withEndAction递归调用动画来实现简单的重复。

例子:

private var animationCount = 0

private fun gyrate() {
    val scale = if (animationCount++ % 2 == 0) 0.92f else 1f
    animate().scaleX(scale).scaleY(scale).setDuration(725).withEndAction(::gyrate)
}

这段代码会重复地改变一个视图的大小,使其缩小,恢复正常大小,再次缩小,恢复正常大小,以此类推。这是一种非常简单的模式,可以用于重复任何你想要的动画效果。


1
这个解决方案存在问题。当你最小化应用程序时,这段代码仍然会运行。因此,在应用程序最小化时需要暂停(取消)动画,并在再次打开应用程序时重新启动。 - Aleksandr Urzhumtcev

7
这是可以实现的。以下是旋转视图的示例:
        final ViewPropertyAnimator animator = view.animate().rotation(360).setInterpolator(new LinearInterpolator()).setDuration(1000);

        animator.setListener(new android.animation.Animator.AnimatorListener() {
            ...

            @Override
            public void onAnimationEnd(final android.animation.Animator animation) {
                animation.setListener(null);
                view.setRotation(0);
                view.animate().rotation(360).setInterpolator(new LinearInterpolator()).setDuration(1000).setListener(this).start();
            }

        });

您还可以使用 "withEndAction" 代替监听器。


使用 "withEndAction" 方法代替监听器。

0
final ViewPropertyAnimator animator = view.animate().rotation(360).setInterpolator(new LinearInterpolator()).setDuration(1000); //Animator object

    animator.setListener(new android.animation.Animator.AnimatorListener() {
        ...

        @Override
        public void onAnimationEnd(final android.animation.Animator animation) {
            animation.setListener(this); //It listens for animation's ending and we are passing this to start onAniationEnd method when animation ends, So it works in loop
            view.setRotation(0);
            view.animate().rotation(360).setInterpolator(new LinearInterpolator()).setDuration(1000).setListener(this).start();
        }

    });

虽然这段代码可能回答了问题,但提供解决问题的方式和原因可以提高其长期价值。 - L_J

0
在 Kotlin 中,您可以这样做。创建一个可运行的对象,在其中对视图进行动画处理,并将 withEndAction 设置为可运行对象本身。最后,运行可运行对象以启动动画。
var runnable: Runnable? = null
runnable = Runnable {
    view.animate()
        .setDuration(10000)
        .rotationBy(360F)
        .setInterpolator(LinearInterpolator())
        .withEndAction(runnable)
        .start()
}
runnable.run()

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