Natalie Le
Natalie Le

Reputation: 23

How to make an AnimationSet repeat?

I have 2 Animations in my AnimationSet. They need to happen sequentially and are different durations. How can I make my AnimationSet repeat infinitely?

public void cartoonBreathing(ImageView v, int inhale_time, int exhale_time){
    AnimationSet breathing_set = new AnimationSet(true);

    Animation inhale = new ScaleAnimation(1.0f,2f,1.0f,2f,
            Animation.RELATIVE_TO_SELF,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f);
    inhale.setFillAfter(true);
    inhale.setDuration(inhale_time * 1000);

    Animation exhale = new ScaleAnimation(1.0f,0.5f,1.0f,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f);
    exhale.setFillAfter(true);
    exhale.setDuration(exhale_time * 1000);

    breathing_set.addAnimation(inhale);
    breathing_set.addAnimation(exhale);

    //breathing_set.setRepeatMode(Animation.RESTART); DOES NOT WORK
    //breathing_set.setRepeatMode(2); DOES NOT WORK
    //breathing_set.setRepeatCount(Animation.INFINITE);

    v.startAnimation(breathing_set);

}

Upvotes: 2

Views: 1339

Answers (1)

Bö macht Blau
Bö macht Blau

Reputation: 13009

Quoting from the documentation on AnimationSet:

The way that AnimationSet inherits behavior from Animation is important to understand. Some of the Animation attributes applied to AnimationSet affect the AnimationSet itself, some are pushed down to the children, and some are ignored, as follows:

  • duration, repeatMode, fillBefore, fillAfter: These properties, when set on an AnimationSet object, will be pushed down to all child animations.
  • repeatCount, fillEnabled: These properties are ignored for AnimationSet.
  • startOffset, shareInterpolator: These properties apply to the AnimationSet itself.

This explains why your attempts were unsuccessful. Instead, you can use an Animation.AnimationListener to restart the animation once it is finished:

public void cartoonBreathing(final ImageView v, int inhale_time, int exhale_time){
    final AnimationSet breathing_set = new AnimationSet(true);

    Animation inhale = new ScaleAnimation(1.0f,2f,1.0f,2f,
            Animation.RELATIVE_TO_SELF,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f);
    inhale.setFillAfter(true);
    inhale.setDuration(inhale_time * 1000);

    Animation exhale = new ScaleAnimation(1.0f,0.5f,1.0f,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f);
    exhale.setFillAfter(true);
    exhale.setDuration(exhale_time * 1000);

    breathing_set.addAnimation(inhale);
    breathing_set.addAnimation(exhale);

    breathing_set.setAnimationListener(new Animation.Animation.AnimationListener()
    {
        @Override
        public void onAnimationStart(Animation animation){}

        @Override
        public void onAnimationEnd(Animation animation)
        {
            v.startAnimation(breathing_set);
        }

        @Override
        public void onAnimationRepeat(Animation animation){}
    });

    v.startAnimation(breathing_set);
}

Please note that the ImageView and the AnimationSet have to be declared final in order to be accessible from within the AnimationListener

And maybe consider calling clearAnimation() on the ImageView if the app is stopped.

Upvotes: 2

Related Questions