tag studio example español attribute android animation listener android-vectordrawable

android - studio - title html español



¿Hay alguna forma de escuchar el final de la animación en AnimatedVectorDrawables? (4)

Aún no lo he intentado, pero Android 6.0 tiene un método registerAnimationCallback de la interfaz Animatable2 para esto

Edición: sí, esto funciona en el emulador de Android 6.0:

mAnimatedVectorDrawable.registerAnimationCallback (new Animatable2.AnimationCallback(){ public void onAnimationEnd(Drawable drawable){ //Do something } }

Edit2: parece que no han agregado soporte para esto en AnimatedVectorDrawableCompat desde el soporte lib 23.2+ :(

Edit3: parece que esto se agregó en soporte lib 25.3.0

Gracias Carson!

He creado un AnimatedVectorDrawable, funciona bastante bien, ahora estoy buscando una manera de cambiar la animación u ocultar la vista después de que termine. Esperaba que hubiera un oyente, pero no parece que lo haya. ¿Alguien puede ayudar?

EDITAR

Así que encontré una solución alternativa, pero no una forma muy elegante. Lo que hice fue crear un hilo y una encuesta si la animación se está ejecutando.

new Runnable() { public void run() { while(mLoop) { if(mAnimatedVectorDrawable.isRunning()) { Thread.sleep(mPollingInterval); } else { mLoop = false; // TODO what ever } } } };

Si alguien encuentra una solución mejor, por favor comparta.


Encontré el mismo problema. Estoy tratando de animar un círculo que se está dibujando y una marca dentro.

Lo mejor que pude hacer es jugar con duraciones. Algo como esto:

final Drawable drawable = circle.getDrawable(); final Animatable animatable = (Animatable) drawable; animatable.start(); tick.setAlpha(0f); tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start(); final Drawable drawable2 = tick.getDrawable(); final Animatable animatable2 = (Animatable) drawable2; animatable2.start();

Sería genial tener un oyente


Es extraño que no haya una API directa para obtener esto. Supongo que una solución alternativa que no implique sustituciones sería simplemente encontrar la animación en su conjunto de animaciones que requiera la mayor cantidad de tiempo y luego publicar un runnable retrasado para ocultar la vista.

int longestAnimationTime = 500; //miliseconds, defined in XML possibly? drawable.start(); drawableView.postDelayed(new Runnable() { @Override public void run() { drawableView.setVisibility(View.GONE); } }, longestAnimationTime);

El inconveniente es que involucra la codificación de tu tiempo de animación más largo, pero siempre que estés haciendo referencia al mismo valor constante tanto en el XML de la animación como en el código, funcionará correctamente, no se necesitan anulaciones.


Mi primer instinto fue tomar el código fuente, agregar algunas devoluciones de llamada y crear un dibujable personalizado a partir de él. Por supuesto, eso no habría significado ningún soporte xml.

Resulta que AnimatedVectorDrawable utiliza los VectorDrawable''s privados VectorDrawable''s . Por lo tanto, este enfoque no funcionará.

Podríamos crear una clase envoltura simple alrededor de AnimatedVectorDrawable y agregar devoluciones de llamada:

public class AVDWrapper { private Handler mHandler; private Animatable mDrawable; private Callback mCallback; private Runnable mAnimationDoneRunnable = new Runnable() { @Override public void run() { if (mCallback != null) mCallback.onAnimationDone(); } }; public interface Callback { public void onAnimationDone(); public void onAnimationStopped(); } public AVDWrapper(Animatable drawable, Handler handler, Callback callback) { mDrawable = drawable; mHandler = handler; mCallback = callback; } // Duration of the animation public void start(long duration) { mDrawable.start(); mHandler.postDelayed(mAnimationDoneRunnable, duration); } public void stop() { mDrawable.stop(); mHandler.removeCallbacks(mAnimationDoneRunnable); if (mCallback != null) mCallback.onAnimationStopped(); } }

Su código se vería como:

final Drawable drawable = circle.getDrawable(); final Animatable animatable = (Animatable) drawable; AVDWrapper.Callback callback = new AVDWrapper.Callback() { @Override public void onAnimationDone() { tick.setAlpha(1f); } @Override public void onAnimationStopped() { // Okay } }; AVDWrapper avdw = new AVDWrapper(animatable, mHandler, callback); //animatable.start(); avdw.start(2000L); tick.setAlpha(0f); //tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start(); // One wrapper is sufficient if the duration is same final Drawable drawable2 = tick.getDrawable(); final Animatable animatable2 = (Animatable) drawable2; animatable2.start();

Pero, esto es exactamente lo que estás haciendo con setStartDelay . Así que no sé cuán útil será esto.

Edición: Todo esto también se puede implementar dentro de un AnimatedVectorDrawable extendido. Pero, perderás el soporte xml por completo.