OnAnimationEnd no se llama, onAnimationStart funciona bien

Tengo un ScrollView en el PopupWindow. Estoy animando los contenidos de ScrollView con TranslateAnimation.

Cuando se inicia la animación, se llama al escucha onAnimationStart, pero no se llama a onAnimationEnd. Algunas ideas ?

Diseño :

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/popup_window_bg" android:layout_width="match_parent" android:layout_height="wrap_content"> <View android:layout_width="@dimen/toolbar_padding_left" android:layout_height="@dimen/toolbar_height"/> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+web/toolbar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scrollbars="none" android:visibility="invisible"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> ... </LinearLayout> </ScrollView> </LinearLayout> 

Código de animación:

 mToolbar = mPopupContents.findViewById( R.web.toolbar ); TranslateAnimation anim = new TranslateAnimation(0, 0, -60, 0); anim.setDuration(1000); anim.setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation a) { Log.d(LOGTAG, "---- animation start listener called" ); } public void onAnimationRepeat(Animation a) {} public void onAnimationEnd(Animation a) { Log.d(LOGTAG, "---- animation end listener called" ); } }); mToolbar.startAnimation(anim); 

Actualización : Comprobé que se llama onAnimationEnd pero se llama después de un cierto retraso (siempre que no inicie la nueva animación durante ese tiempo).

AnimationEnd no es confiable. Si no desea volver a escribir su código con vistas personalizadas que anulan OnAnimationEnd, use postDelayed .

He aquí algunos ejemplos de código:

 final FadeUpAnimation anim = new FadeUpAnimation(v); anim.setInterpolator(new AccelerateInterpolator()); anim.setDuration(1000); anim.setFillAfter(true); new Handler().postDelayed(new Runnable() { public void run() { v.clearAnimation(); //Extra work goes here } }, anim.getDuration()); v.startAnimation(anim); 

Si bien puede parecer feo, puedo garantizar que es muy fiable. Lo utilizo para ListViews que están insertando nuevas filas mientras se quita con animación a otras filas. El estrés que prueba a un oyente con AnimationEnd resultó poco fiable. A veces AnimationEnd nunca se activó. Es posible que desee volver a aplicar cualquier transformación en la función postDelayed en caso de que la animación no terminó completamente, pero eso realmente depende de qué tipo de animación que está utilizando.

Después de que no recuerdo cómo pueden los posts leídos y los días pasados ​​encontrar una solución para este problema descubrí que si el objeto a mover no está en la región de la pantalla (por ejemplo se coloca fuera de las coords de la pantalla) OnAnimationEnd la devolución de llamada no está consiguiendo llamado. Probablemente la animación falla justo después de iniciado (método de inicio se llama, codifiqué un oyente) pero nada se escribe en logcat. Tal vez este no es exactamente su caso, pero esto finalmente resuelto mi problema y espero que pueda ayudarle también.

Asegúrese de que está USANDO view.startAnimation(Animation) Y NO view.setAnimation(Animation) . Esta simple confusión puede ser un problema.

-Aclamaciones

Además, al utilizar animaciones, no olvide setFillAfter() a true .

http://developer.android.com/reference/android/view/animation/Animation.html#setFillAfter(boolean)

Si fillAfter es true, la transformación que realiza esta animación persistirá cuando termine. El valor predeterminado es false si no se establece. Tenga en cuenta que esto se aplica cuando se utiliza AnimationSet para encadenar animaciones. La transformación no se aplica antes de que el propio AnimationSet se inicie.

 anim.setFillAfter(true); mToolbar.startAnimation(anim); 

Para cualquier persona que tropieza con esta pregunta: Considere la posibilidad de cambiar a utilizar el sistema de animación de propiedad en lugar de http://developer.android.com/guide/topics/graphics/prop-animation.html

He tenido varios problemas con la vieja manera de animar un fade-in / out en una vista (a través de AlphaAnimation). OnAnimationEnd no estaba siendo llamado etc … Con la Animación de Propiedades todos esos problemas fueron resueltos.

Si quieres soportar dispositivos API <11, https://github.com/JakeWharton/NineOldAndroids de Jake Wharton es el camino a seguir

¿No está configurando otra animación antes de que la que está esperando termina?

Sin contexto es difícil de entender si es algo así … pero es probablemente una de las únicas cosas que lo causaría.

Supongo que se llama después de algún tiempo debido a que está utilizando setDuration para la animación y pasando 1000 ms en ella. Simplemente pase 0 y no tardará un tiempo en llamarse.

El retraso se debe probablemente a la anim.setDuration (1000) o si está haciendo esto en un hilo, probablemente debido a la conmutación de contexto. Trate de manipular el tiempo de retardo y ver si nota alguna diferencia.

Intente utilizar overridePendingAnimation (int, int). Ie overridePendingAnimation (0,0)

Anulará su animación predeterminada y luego podrá definir su propia animación Al llamar al método startAnimation utilizando el objeto de View.

Aquí está mi código de ejemplo. No sé si será útil para usted o no.

 overridePendingTransition(0,0); //finish(); v.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fadeout)); startActivity(new Intent(ContentManagerActivity.this,Mainmenu_activity.class)); overridePendingTransition(R.anim.fadein,0); 

He intentado su código que está trabajando muy bien en OnAnimation iniciar y inAmimationEnd también, después de tiempo de duración significa que después de terminar animación onAnimationEnd se llama, por lo que su código de trabajo bien

 TranslateAnimation anim =new TranslateAnimation(0, 0, -60, 0); anim.setDuration(1000); anim.setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation a) { Log.w("Start", "---- animation start listener called" ); } public void onAnimationRepeat(Animation a) {} public void onAnimationEnd(Animation a) { Log.d(" end ","---- animation end listener called" ); } }); mIv.setAnimation(anim); mIv.startAnimation(anim); 

Podría haber alguien que aún tiene este problema y no se encontró una solución -aunque lee un montón de respuestas stackoverflow- como yo!

Así que mi caso fue: He utilizado animatorSet y

  1. No había una sola vista que podría llamar a clearAnimation,
  2. No estaba llamando a mi animación de backgroundThread -que nunca debería hacer eso, btw-

Como una solución, he llamado animatorSet.end() justo antes de animatorSet.start()

Cuando se inicia un comando de animación en una vista que está parcialmente fuera de pantalla, se inicia la animación y se llama al onStartListener, pero la animación no se ejecuta completamente (de alguna manera se interrumpe en el medio). Mi conjetura es que, como la vista es offscreen, se cancela y por lo tanto es onFinish no se llama. Como una solución para que he creado mi propio oyente de animación que inicia un controlador y utiliza postDelayed para notificar al usuario del evento final de animación. En Kotlin:

 abstract class PartiallyOffScreenAnimationListener : Animation.AnimationListener, AnimationListener { override fun onAnimationRepeat(animation: Animation?) { onAnimationRepeat_(animation) } override fun onAnimationEnd(animation: Animation) {} override fun onAnimationStart(animation: Animation) { onAnimationStart_(animation) Handler().postDelayed({ onAnimationEnd_(animation) animation.setAnimationListener(null) }, animation.duration + 50) } } 

Tenga en cuenta que, en el caso de que la animación no se ejecute completamente, la vista puede quedar en un estado incoherente (por ejemplo, animar los parámetros de diseño puede llevar a un extraño factor de interpolador intermedio que se va a caer. La devolución de llamada final que la vista está en el estado deseado.Si no, simplemente establezca manualmente.

Hazlo como belows

  1. Hacer animación final
  2. Invocarlo dentro de un manejador
  3. El oyente debe instanciarse una vez.
  4. Animación clara.

Por ejemplo view.clearAnimation ();

 new Hander().post( run() { final TranslateAnimation ani = new TranslateAnimation(0, 0, 0, 0); ani.setAnimationListener(mListener); } ); private Animation.AnimationListener mListener = new Animation.AnimationListener() { } 

¿Dónde comienzas tu animación? Si en onCreate, está mal. Intenta hacerlo en onResume.

  • GLSurfaceView en un PopupWindow
  • PopupWindow en android
  • Cómo obtener información de una ventana emergente
  • anclado PopupWindow y SOFT_INPUT_ADJUST_RESIZE android
  • Android PopupWindow showAsDropDown () no funciona correctamente
  • Desenfoque o fondo oscuro cuando Android PopupWindow está activo
  • SurfaceView no funciona dentro de PopupWindow
  • Android - PopupWindow sobre una vista específica
  • Crear correctamente un fragmento en un PopupWindow
  • PopupWindow de Android / Diálogo
  • La actividad de diálogo se oculta bajo la pantalla de llamada cuando el bloqueo seguro está activado, android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.