259

I need to stop a running translate animation. The .cancel() method of Animation has no effect; the animation goes until the end anyway.

How do you cancel a running animation?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Mix
  • 3,003
  • 2
  • 15
  • 14

9 Answers9

527

Call clearAnimation() on whichever View you called startAnimation().

CommonsWare
  • 910,778
  • 176
  • 2,215
  • 2,253
  • 1
    But in fact I need a bit more complex thing: when animation stop, it must remain in current position, i.e. I have sliding image and on touch event it must freeze on this place. clearAnimation() is not a case, because it resets state to start/end position depending on setFillAfter() – Mix Nov 06 '10 at 09:56
  • 1
    @user349871: `setFillAfter()` probably does not do what you think it does, anyway. When the touch event occurs, clear the animation and then adjust your layout to affect whatever permanent change you seek. – CommonsWare Nov 06 '10 at 10:00
  • Ok, good, I will try to stop animation by calling clearAnimation(). Next step is to find position where animation has been before I stop it. What API is for that? – Mix Nov 06 '10 at 10:03
  • @Mix: There is no API for that. – CommonsWare Nov 06 '10 at 10:21
  • 7
    Hi again! I have found a way to get point (in terms of interpolated time) when animation was canceled. You need to make Animation sub-class and put there code from android code animation (e.g. TranslateAnimation). In your class you will be able to save and track position in applyTransformation() function. – Mix Nov 07 '10 at 21:23
44

On Android 4.4.4, it seems the only way I could stop an alpha fading animation on a View was calling View.animate().cancel() (i.e., calling .cancel() on the View's ViewPropertyAnimator).

Here's the code I'm using for compatibility before and after ICS:

public void stopAnimation(View v) {
    v.clearAnimation();
    if (canCancelAnimation()) {
        v.animate().cancel();
    }
}

... with the method:

/**
 * Returns true if the API level supports canceling existing animations via the
 * ViewPropertyAnimator, and false if it does not
 * @return true if the API level supports canceling existing animations via the
 * ViewPropertyAnimator, and false if it does not
 */
public static boolean canCancelAnimation() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}

Here's the animation that I'm stopping:

v.setAlpha(0f);
v.setVisibility(View.VISIBLE);
// Animate the content view to 100% opacity, and clear any animation listener set on the view.
v.animate()
    .alpha(1f)
    .setDuration(animationDuration)
    .setListener(null);
Sean Barbeau
  • 10,950
  • 8
  • 53
  • 107
23

If you are using the animation listener, set v.setAnimationListener(null). Use the following code with all options.

v.getAnimation().cancel();
v.clearAnimation();
animation.setAnimationListener(null);
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
DjP
  • 3,957
  • 2
  • 21
  • 30
5

You must use .clearAnimation(); method in UI thread:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        v.clearAnimation();
    }
});
Paula
  • 59
  • 1
  • 6
Aleksandr Gorshkov
  • 453
  • 1
  • 6
  • 15
4

What you can try to do is get the transformation Matrix from the animation before you stop it and inspect the Matrix contents to get the position values you are looking for.

Here are the api's you should look into

public boolean getTransformation (long currentTime, Transformation outTransformation)

public Matrix getMatrix ()

public void getValues (float[] values)

So for example (some pseudo code. I have not tested this):

Transformation outTransformation = new Transformation();
myAnimation.getTransformation(currentTime, outTransformation);
Matrix transformationMatrix = outTransformation.getMatrix();
float[] matrixValues = new float[9];
transformationMatrix.getValues(matrixValues);
float transX = matrixValues[Matrix.MTRANS_X];
float transY = matrixValues[Matrix.MTRANS_Y];
Franci Penov
  • 71,783
  • 15
  • 124
  • 160
Akos Cz
  • 12,271
  • 1
  • 35
  • 31
  • Where do we get currentTime? – mako Sep 28 '13 at 09:43
  • Oh, the documentation says it corresponds to the "wall clock", elsewhere they define the wall clock as System.currentTimeMillis(), which corresponds to calender time and will jump whenever the time is changed by the user or the network. An odd measure to be using. – mako Sep 28 '13 at 09:57
0

Use the method setAnimation(null) to stop an animation, it exposed as public method in View.java, it is the base class for all widgets, which are used to create interactive UI components (buttons, text fields, etc.). /** * Sets the next animation to play for this view. * If you want the animation to play immediately, use * {@link #startAnimation(android.view.animation.Animation)} instead. * This method provides allows fine-grained * control over the start time and invalidation, but you * must make sure that 1) the animation has a start time set, and * 2) the view's parent (which controls animations on its children) * will be invalidated when the animation is supposed to * start. * * @param animation The next animation, or null. */ public void setAnimation(Animation animation)

saurabh dhillon
  • 750
  • 7
  • 17
0

To stop animation you may set such objectAnimator that do nothing, e.g.

first when manual flipping there is animation left to right:

flipper.setInAnimation(leftIn);
flipper.setOutAnimation(rightOut);

then when switching to auto flipping there's no animation

flipper.setInAnimation(doNothing);
flipper.setOutAnimation(doNothing);

doNothing = ObjectAnimator.ofFloat(flipper, "x", 0f, 0f).setDuration(flipperSwipingDuration);
Andrew Glukhoff
  • 811
  • 9
  • 8
0

First of all, remove all the listeners which are related to the animatior or animator set. Then cancel the animator or animator set.

 inwardAnimationSet.removeAllListeners()
        inwardAnimationSet.cancel()
Sahil Bansal
  • 207
  • 3
  • 3
0

use this way:

// start animation
TranslateAnimation anim = new TranslateAnimation( 0, 100 , 0, 100);
anim.setDuration(1000);
anim.setFillAfter( true );
view.startAnimation(anim);

// end animation or cancel that
view.getAnimation().cancel();
view.clearAnimation();

cancel()

Cancel the animation. Canceling an animation invokes the animation listener, if set, to notify the end of the animation. If you cancel an animation manually, you must call reset() before starting the animation again.


clearAnimation()

Cancels any animations for this view.


Rasoul Miri
  • 5,433
  • 43
  • 52