So stoppen Sie eine Animation (cancel () funktioniert nicht)


244

Ich muss eine laufende Übersetzungsanimation stoppen. Die .cancel()Methode von Animationhat keine Wirkung; Die Animation läuft sowieso bis zum Ende.

Wie brechen Sie eine laufende Animation ab?

Antworten:


508

Rufen Sie clearAnimation()an, was auch immer ViewSie angerufen haben startAnimation().


Tatsächlich brauche ich etwas Komplexeres: Wenn die Animation stoppt, muss sie in der aktuellen Position bleiben, dh ich habe ein gleitendes Bild und bei Berührung muss sie an dieser Stelle einfrieren. clearAnimation () ist kein Fall, da es den Status abhängig von setFillAfter ()
Mix

1
@ user349871: macht setFillAfter()wahrscheinlich sowieso nicht das, was du denkst. Wenn das Berührungsereignis auftritt, löschen Sie die Animation und passen Sie dann Ihr Layout an, um die von Ihnen gewünschten dauerhaften Änderungen zu beeinflussen.
CommonsWare

Ok, gut, ich werde versuchen, die Animation zu stoppen, indem ich clearAnimation () aufrufe. Der nächste Schritt besteht darin, die Position zu finden, an der sich die Animation befunden hat, bevor ich sie stoppe. Welche API ist dafür?
Mischen Sie den

@Mix: Dafür gibt es keine API.
CommonsWare

7
Hallo nochmal! Ich habe einen Weg gefunden, um den Punkt (in Bezug auf die interpolierte Zeit) zu ermitteln, an dem die Animation abgebrochen wurde. Sie müssen Animation zur Unterklasse machen und dort Code aus Android-Code-Animation (z. B. TranslateAnimation) einfügen. In Ihrer Klasse können Sie die Position in der Funktion applyTransformation () speichern und verfolgen.
Mischen Sie

40

Unter Android 4.4.4 war es anscheinend die einzige Möglichkeit, eine Alpha-Fading-Animation in einer Ansicht zu stoppen, das Aufrufen View.animate().cancel()(dh das Aufrufen .cancel()der Ansicht ViewPropertyAnimator).

Hier ist der Code, den ich aus Kompatibilitätsgründen vor und nach ICS verwende:

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

... mit der Methode:

/**
 * 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;
}

Hier ist die Animation, die ich stoppe:

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

.setListener(null);das hat mir geholfen.
Muhammad Saqib

18

Wenn Sie den Animations-Listener verwenden, stellen Sie ein v.setAnimationListener(null). Verwenden Sie den folgenden Code mit allen Optionen.

v.getAnimation().cancel();
v.clearAnimation();
animation.setAnimationListener(null);

2
Es ist nicht erforderlich anzurufen, v.setAnimation(null);da dies in erfolgt v.clearAnimation();.
Christian

Wie @Christian sagte, ist v.setAnimation (null) nicht erforderlich
akshay bhange

5

Sie müssen .clearAnimation () verwenden. Methode im UI-Thread:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        v.clearAnimation();
    }
});

3

Sie können versuchen, die Transformationsmatrix aus der Animation abzurufen, bevor Sie sie stoppen, und den Matrixinhalt überprüfen, um die gewünschten Positionswerte zu erhalten.

Hier sind die APIs, in die du schauen solltest

public boolean getTransformation (long currentTime, Transformation outTransformation)

public Matrix getMatrix ()

public void getValues (float[] values)

Also zum Beispiel (ein Pseudocode. Ich habe dies nicht getestet):

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];

Woher bekommen wir currentTime?
Mako

Oh, die Dokumentation sagt, dass es der "Wanduhr" entspricht, an anderer Stelle definieren sie die Wanduhr als System.currentTimeMillis (), was der Kalenderzeit entspricht und springt, wenn die Zeit vom Benutzer oder vom Netzwerk geändert wird. Eine seltsame Maßnahme.
Mako

0

Verwenden Sie die Methode setAnimation (null) , um eine Animation zu stoppen. Sie wird in View.java als öffentliche Methode verfügbar gemacht . Sie ist die Basisklasse für alle Widgets , mit denen interaktive UI-Komponenten (Schaltflächen, Textfelder usw.) erstellt werden. /** * 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)


0

Um die Animation zu stoppen, können Sie einen solchen objectAnimator festlegen, der nichts tut, z

Beim manuellen Umdrehen erfolgt zunächst eine Animation von links nach rechts:

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

Wenn Sie dann auf Auto Flipping umschalten, erfolgt keine Animation

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

doNothing = ObjectAnimator.ofFloat(flipper, "x", 0f, 0f).setDuration(flipperSwipingDuration);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.