studio example android animation popupwindow

android - example - onAnimationEnd no se llama, onAnimationStart funciona bien



popupwindow android (14)

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

Tengo un ScrollView en la ventana emergente. Estoy animando los contenidos de ScrollView usando TranslateAnimation.

Cuando se inicia la animación, se llama al oyente 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 a onAnimationEnd pero se invoca después de un cierto retraso (siempre que no se inicie la nueva animación durante ese tiempo).


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

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


Además, cuando use animaciones, no olvide establecer setFillAfter() en true .

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

Si fillAfter es verdadero, la transformación que esta animación realizó persistirá cuando haya terminado. El valor predeterminado es falso si no está establecido. Tenga en cuenta que esto se aplica cuando se usa un AnimationSet para encadenar animaciones. La transformación no se aplica antes de que comience el propio AnimationSet.

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


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


Cuando inicia un comando de animación en una vista que está parcialmente fuera de pantalla, la animación comienza y se llama al OnStartListener, pero la animación no se ejecuta completamente (de alguna manera se interrumpe en el medio). Supongo que, como la vista es fuera de la pantalla, se cancela y, por lo tanto, está activada. No se llama. Como una solución para eso, creé mi propio oyente de animación que comenzó como controlador y usa postDelayed para notificar al usuario del evento final de la 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 por completo, la vista puede dejarse en un estado incoherente (por ejemplo, la animación de los parámetros de diseño puede ocasionar que se pierda un factor de interpolador medio extraño. Por ese motivo, debe verificar a la devolución de llamada final indica que la vista está en el estado deseado. De lo contrario, simplemente configúrelo manualmente.


Después de que no recuerdo cómo se pueden leer las publicaciones y los días dedicados a encontrar una solución para este problema, descubrí que si el objeto para mover no está en la región de la pantalla (por ejemplo, está fuera de los coords de la pantalla) OnAnimationEnd callback llamado. Probablemente la animación falla justo después de iniciarse (se llama al método start, codifiqué un oyente) pero no se escribe nada en logcat. Tal vez este no sea exactamente tu caso, pero esto finalmente resolvió mi problema y espero que pueda ayudarte también.


Hazlo como belows

  1. hacer la animación final
  2. invocarlo dentro de un controlador
  3. oyente debe ser instanciado 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() { }


Intente utilizar anular la animación de publicación (int, int). es decir, anula la animación anticipada (0,0)

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

Aquí está mi código de ejemplo. No sé si te será útil 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);


La demora probablemente se deba a anim.setDuration (1000) o si está haciendo esto en un hilo, probablemente debido al cambio de contexto. Intente manipular el tiempo de demora y vea si nota alguna diferencia.


Para cualquiera que se tropiece con esta pregunta: considere cambiar al uso del sistema de Animación de propiedades en su lugar http://developer.android.com/guide/topics/graphics/prop-animation.html

He tenido varios problemas con la antigua forma de animar un fundido de entrada / salida en una vista (a través de AlphaAnimation). OnAnimationEnd no se llamaba, etc. Con la animación de propiedades, todos esos problemas se resolvieron.

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


Probé tu código, funciona bien en OnAnimation start y en Amimation End también, después de que el tiempo de duración significa después de finalizar la animación en AnimationEnd, así que tu código funciona 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);


Puede haber alguien que todavía tenga este problema y no haya encontrado una solución -aunque haya leído muchas respuestas de - ¡como yo!

Así que mi caso fue: utilicé animatorSet y

  1. no había una sola vista a la que pudiera llamar clearAnimation,
  2. No estaba llamando a mi animación desde backgroundThread, que nunca debes hacer eso, por cierto

Como solución, llamé a animatorSet.end() justo antes de animatorSet.start()


Supongo que se llama después de algún tiempo porque estás usando setDuration para animación y pasando 1000 ms en él. Solo pase 0 y no demorará en llamar.


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

Aquí hay un código de ejemplo:

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 confiable. Lo uso para ListViews que están insertando nuevas filas al eliminar con animación a otras filas. El estrés al probar a un oyente con AnimationEnd resultó poco confiable. 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 termine por completo, pero eso realmente depende del tipo de animación que esté utilizando.