Jak zatrzymać animację (anulowanie () nie działa)

245

Muszę zatrzymać uruchomioną animację tłumaczenia. .cancel()Sposób Animationnie ma wpływu; animacja i tak trwa do końca.

Jak anulować uruchomioną animację?

Mieszać
źródło

Odpowiedzi:

509

Zadzwoń clearAnimation()na dowolny Viewzadzwoniłeś startAnimation().

CommonsWare
źródło
Ale tak naprawdę potrzebuję nieco bardziej złożonej rzeczy: gdy animacja się zatrzyma, musi pozostać w aktualnej pozycji, tzn. Mam przesuwany obraz, a po dotknięciu musi zamarznąć w tym miejscu. clearAnimation () nie jest przypadkiem, ponieważ resetuje stan do pozycji początkowej / końcowej w zależności od setFillAfter ()
Mix
1
@ user349871: setFillAfter()prawdopodobnie i tak nie robi tego, co myślisz. Kiedy wystąpi zdarzenie dotykowe, wyczyść animację, a następnie dostosuj układ, aby wpłynąć na każdą stałą zmianę, której szukasz.
CommonsWare
Ok, dobrze, spróbuję zatrzymać animację, wywołując clearAnimation (). Następnym krokiem jest znalezienie pozycji, w której była animacja, zanim ją zatrzymam. Co to jest interfejs API?
Mix
@ Mix: Nie ma do tego API.
CommonsWare
7
Witaj ponownie! Znalazłem sposób na uzyskanie punktu (pod względem interpolowanego czasu), kiedy animacja została anulowana. Musisz utworzyć podklasę Animacja i umieścić tam kod z animacji kodu Androida (np. TranslateAnimation). W swojej klasie będziesz mógł zapisać i śledzić pozycję w funkcji applyTransformation ().
Mix
40

Na Androidzie 4.4.4 wydaje się, że jedynym sposobem, w jaki mógłbym zatrzymać animację zanikania alfa w Widoku, było wywołanie View.animate().cancel()(tj. Wywołanie .cancel()w Widoku ViewPropertyAnimator).

Oto kod używam do kompatybilności przed i po ICS:

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

... metodą:

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

Oto animacja, którą zatrzymuję:

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
źródło
.setListener(null);to mi pomogło.
Muhammad Saqib
18

Jeśli używasz nasłuchiwania animacji, ustaw v.setAnimationListener(null). Użyj następującego kodu ze wszystkimi opcjami.

v.getAnimation().cancel();
v.clearAnimation();
animation.setAnimationListener(null);
DjP
źródło
2
Dzwonienie nie jest konieczne, v.setAnimation(null);ponieważ zostanie to zrobione w v.clearAnimation();.
Christian
Jak powiedział @Christian, v.setAnimation (null) nie jest wymagane
akshay bhange
5

Musisz użyć .clearAnimation (); metoda w wątku interfejsu użytkownika:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        v.clearAnimation();
    }
});
rz0
źródło
3

Możesz zatrzymać matrycę transformacji z animacji przed jej zatrzymaniem i sprawdzić zawartość matrycy, aby uzyskać poszukiwane wartości pozycji.

Oto api, na które powinieneś spojrzeć

public boolean getTransformation (long currentTime, Transformation outTransformation)

public Matrix getMatrix ()

public void getValues (float[] values)

Na przykład (jakiś pseudo kod. Nie testowałem tego):

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];
Akos Cz
źródło
Skąd bierzemy currentTime?
mako
Och, dokumentacja mówi, że odpowiada on „zegarowi ściennemu”, gdzie indziej określają zegar ścienny jako System.currentTimeMillis (), który odpowiada czasowi kalendarza i przeskakuje za każdym razem, gdy czas zostanie zmieniony przez użytkownika lub sieć. Dziwna miara do użycia.
mako
0

Użyj metody setAnimation (null), aby zatrzymać animację, jest ona widoczna jako metoda publiczna w View.java , jest to klasa podstawowa dla wszystkich widżetów , które są używane do tworzenia interaktywnych składników interfejsu użytkownika (przyciski, pola tekstowe itp.). /** * 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
źródło
0

Aby zatrzymać animację, możesz ustawić taki obiektAnimator, który nic nie robi, np

po pierwsze przy ręcznym przerzucaniu od lewej do prawej jest animacja:

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

wtedy po przełączeniu na automatyczne odwracanie nie ma animacji

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

doNothing = ObjectAnimator.ofFloat(flipper, "x", 0f, 0f).setDuration(flipperSwipingDuration);
Andrew Glukhoff
źródło