How can I repeat a property animation?
Asked Answered
B

6

11

I'm doing an animation of bubbles on the screen, but the bubbles stop after finishing the animation time. How do I repeat the animation or make it infinite?

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) {
    }
});
Broncho answered 17/8, 2014 at 0:2 Comment(2)
possible duplicate of How to generate looping animation with ViewPropertyAnimator?Ithyphallic
You can also use ValueAnimator which supports repeats, developer.android.com/reference/android/animation/…Saxe
I
16

Since ViewPropertyAnimator is only good for simple animations, use more advanced ObjectAnimator class - basically method setRepeatCount and additionally setRepeatMode.

Isaiah answered 17/8, 2014 at 0:8 Comment(2)
Yes, ViewPropertyAnimator is used for simple animations, for more complex usage, try ObjectAnimator. Sorry for unclear answer.Isaiah
@Isaiah according to the dozen topics in here there is still no good way to repeat an AnimatorSet that consists of two ObjectAnimators. If I missed smth, hit me up, pleaseKort
F
9

You can use CycleInterpolator. For example, like this:

    int durationMs = 60000;
    int cycleDurationMs = 1000;
    view.setAlpha(0f);
    view.animate().alpha(1f)
            .setInterpolator(new CycleInterpolator(durationMs / cycleDurationMs))
            .setDuration(durationMs)
            .start();
Flibbertigibbet answered 2/11, 2016 at 16:41 Comment(1)
How would you make it infinitely animate ?Windshield
A
8

Here is an example in Kotlin with a simple way to repeat the animation by recursively calling it in withEndAction

Example

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

This repeatedly animates the size of a view to get smaller, return to normal, get smaller, return to normal, etc. This is a pretty simple pattern to repeat whatever animation you'd like.

Affirmatory answered 28/6, 2020 at 16:38 Comment(1)
There is a problem with this solution. When you minimize the app this code will still work. So, animation needed to be paused (canceled) when the app is minimized and started again when app is open againDandruff
W
7

This is actually possible. Here's an example of rotating a view:

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

        });

You can also use "withEndAction" instead of a listener.

Windshield answered 6/1, 2016 at 14:1 Comment(0)
S
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();
        }

    });
Schoolteacher answered 30/6, 2018 at 16:53 Comment(1)
While this code may answer the question, providing information on how and why it solves the problem improves its long-term valueTransparent
R
0

in kotlin you can do it like this. create a runnable. inside it animate the view and set withEndAction to runnable itself. and at the end run runnable to animation start.

var runnable: Runnable? = null
runnable = Runnable {
    view.animate()
        .setDuration(10000)
        .rotationBy(360F)
        .setInterpolator(LinearInterpolator())
        .withEndAction(runnable)
        .start()
}
runnable.run()
Rapscallion answered 12/10, 2020 at 4:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.