Come interrompere un'animazione (cancel () non funziona)


245

Devo interrompere un'animazione di traduzione in esecuzione. Il .cancel()metodo di Animationnon ha alcun effetto; l'animazione va comunque fino alla fine.

Come si annulla un'animazione in esecuzione?

Risposte:


509

Chiamata clearAnimation()su qualunque Viewhai chiamato startAnimation().


Ma in realtà ho bisogno di qualcosa di un po 'più complesso: quando l'animazione si ferma, deve rimanere nella posizione corrente, cioè ho un'immagine scorrevole e al tocco deve bloccarsi in questo posto. clearAnimation () non è un caso, perché reimposta lo stato su start / end position a seconda di setFillAfter ()
Mix

1
@ user349871: setFillAfter()probabilmente non fa quello che pensi, comunque. Quando si verifica l'evento touch, cancella l'animazione e regola il layout in modo che influisca su qualsiasi modifica permanente che desideri.
CommonsWare,

Bene, proverò a interrompere l'animazione chiamando clearAnimation (). Il prossimo passo è trovare la posizione in cui è stata l'animazione prima che la fermi. A cosa serve l'API?
Mescola il

@Mix: non esiste un'API per questo.
CommonsWare,

7
Ciao di nuovo! Ho trovato un modo per ottenere il punto (in termini di tempo interpolato) quando l'animazione è stata annullata. Devi creare una sottoclasse di animazione e inserire il codice dall'animazione del codice Android (ad esempio TranslateAnimation). Nella tua classe sarai in grado di salvare e tracciare la posizione nella funzione applyTransformation ().
Mescola il

40

Su Android 4.4.4, sembra che l'unico modo in cui ho potuto interrompere un'animazione di dissolvenza alfa su una vista era chiamare View.animate().cancel()(cioè, chiamare .cancel()sulla vista ViewPropertyAnimator).

Ecco il codice che sto usando per la compatibilità prima e dopo ICS:

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

... con il metodo:

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

Ecco l'animazione che sto fermando:

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);questo mi ha aiutato.
Muhammad Saqib,

18

Se si utilizza il listener di animazioni, impostare v.setAnimationListener(null). Utilizzare il codice seguente con tutte le opzioni.

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

2
Non è necessario chiamare v.setAnimation(null);perché ciò avverrà v.clearAnimation();.
Christian,

Come ha detto @Christian v.setAnimation (null) non è richiesto
akshay bhange

5

Devi usare .clearAnimation (); metodo nel thread dell'interfaccia utente:

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

3

Quello che puoi provare a fare è ottenere la trasformazione Matrix dall'animazione prima di interromperla e ispezionare il contenuto di Matrix per ottenere i valori di posizione che stai cercando.

Ecco le API che dovresti esaminare

public boolean getTransformation (long currentTime, Transformation outTransformation)

public Matrix getMatrix ()

public void getValues (float[] values)

Quindi, ad esempio (alcuni pseudo-codice. Non l'ho provato):

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

Dove otteniamo currentTime?
Mako,

Oh, la documentazione dice che corrisponde al "orologio da parete", altrove definiscono l'orologio da parete come System.currentTimeMillis (), che corrisponde all'ora del calendario e salterà ogni volta che l'ora viene cambiata dall'utente o dalla rete. Una strana misura da usare.
Mako,

0

Utilizzare il metodo setAnimation (null) per interrompere un'animazione, esposta come metodo pubblico in View.java , è la classe di base per tutti i widget , che vengono utilizzati per creare componenti dell'interfaccia utente interattiva (pulsanti, campi di testo, ecc.). /** * 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

Per interrompere l'animazione è possibile impostare un oggetto ObjectAnimator che non faccia nulla, ad es

prima quando si lancia manualmente c'è l'animazione da sinistra a destra:

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

quindi quando si passa al capovolgimento automatico non c'è animazione

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

doNothing = ObjectAnimator.ofFloat(flipper, "x", 0f, 0f).setDuration(flipperSwipingDuration);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.