5

I applied an infinite animation on an ImageView to indicate a running background thread in my app. When the thread finishes, I'm able to stop the animation by using clearAnimation(), but it snaps the ImageView back to its starting position, and I'd like the current animation cycle to complete (which is designed to gracefully end in its starting position). Is there a way to do this?

wirbly
  • 2,183
  • 1
  • 24
  • 24

4 Answers4

7

Just call setRepeatCount(0) and then listen for onAnimationEnd. See here for more details.

Community
  • 1
  • 1
user1431317
  • 2,674
  • 1
  • 21
  • 18
  • Simply setting the repeat count to zero worked for me. I didn't listen for onAnimationEnd, but it seems to work fine. – Henry Oct 01 '12 at 21:09
  • @Henry My use case was a bit more complicated (a refresh button that animates while refreshing), so I needed onAnimationEnd to hide the animated progress indicator, and replace it with the button. Also some workarounds were necessary to make the transition perfectly smooth. See the answer I linked for details. onAnimationEnd is only needed if you need to know when the animation actually stops because it doesn't stop when you call setRepeatCount(0), it finishes the current cycle first (that's the whole point) – user1431317 Dec 14 '12 at 12:54
7

Register an AnimationListener, and wait until onAnimationRepeat() to clear it. I haven't tried this, but I think it will work.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Drat, that would have been perfect except onAnimationRepeat() is not being called, and it appears to be a long-standing bug: http://code.google.com/p/android/issues/detail?id=13397 (onAnimationStart works, and so does onAnimationEnd if I set the animation's repeatCount to a finite number) – wirbly Apr 24 '11 at 23:26
  • 1
    @wirbly: Well, you can try rolling your own "infinite" by doing a single animation, then starting the animation again on `onAnimationEnd()`. Not sure if it will be as smooth as the infinite variety, though. If this worked, though, you'd simply not start the next animation at the end of the one where you want it gone. – CommonsWare Apr 24 '11 at 23:40
2

You can set the desirable position of your animation in the onAnimationEnd() method of your animation listener. Then, instead of going to the initial position, the View will be displayed at the coordinates you set up there.

animation = new TranslateAnimation(0, -length, 0, 0); //setup here your translation parameters
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(10);
animation.setAnimationListener(new Animation.AnimationListener() {
    public void onAnimationStart(Animation animation) {
        animationRunning = true;
    }
    public void onAnimationRepeat(Animation animation) {
    }
    public void onAnimationEnd(Animation animation) {
        animationRunning = false;
        // setAnimationPositionAfterPositionChange();
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) runningText.getLayoutParams();
        params.leftMargin  = currentPosition; //Calculate you current position here
        runningText.setLayoutParams(params);
    }
});
runningText.setAnimation(animation);
0

If you are using animate() you use setListener(null) to stop it the animation, works for me.

    image.animate()
            .translationXBy(-width* 0.5f)
            .setDuration(300)
            .setStartDelay(6000)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    image.animate().rotationBy(90).setDuration(1000).setStartDelay(1).setListener(null);
                }
            });
Andrew Hossam
  • 381
  • 4
  • 12