2011-03-29 11 views
40

Tengo un ScrollView en la ventana emergente. Estoy animando los contenidos de ScrollView usando TranslateAnimation.onAnimationEnd no se llama, onAnimationStart funciona bien

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 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: He verificado que el onAnimationEnd se llama pero se llama después de un cierto retraso (siempre y cuando no se inicia el nuevo animación durante ese tiempo).

+0

El código ayudará. – Wroclai

+0

@Viktor He actualizado la pregunta. – Karan

+0

¿Puedes probar para definirlo dentro de un archivo XML y ver si está funcionando allí? – Wroclai

Respuesta

0

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

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

+0

No. No estoy estableciendo ningún otro er animación. También tengo una variable para controlar esto. – Karan

-1

¿Por dónde comienza su animación? Si está en onCreate, está mal. Intenta hacerlo en onResume.

+0

No está en onCreate, se llama después de la interacción del usuario. – Karan

3

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

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

Si fillAfter es cierto, la transformación que se lleva a cabo esta animación persistirá cuando esté 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); 
0

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

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.

0

Intenta usar overridePendingAnimation (int, int). decir overridePendingAnimation (0,0)

Se anulará su animación por defecto y luego se puede definir la animación propia Llamando al startAnimation método que utiliza el objeto de vista.

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); 
0

Me trataron el código que está funcionando bien en OnAnimation inicio y inAmimationEnd también, después de los medios tiempo de duración después de onAnimationEnd animación acabado se llama, por lo que su 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); 
52

AnimationEnd no es fiable. 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 fiable. 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 finalice por completo, pero eso realmente depende del tipo de animación que esté utilizando.

+3

Muchas gracias, @ShortFuse. Estaba luchando para establecer la visibilidad de una vista a 'View.VISIBLE' en' onAnimationStart() 'que no funcionaba para algunas versiones de Android. Después de leer su respuesta, terminé con esto: 'workThatWouldGoInOnAnimationStart();' 'view.postDelayed (workThatWouldGoInOnAnimationEnd(), anim.getDuration());' 'view.startAnimation (anim);' –

8

Después de no recordar cómo se pueden leer las publicaciones y días dedicados a encontrar una solución para este problema, descubrí que si el objeto no se mueve en la región de la pantalla (por ejemplo, está fuera de la pantalla) OnAnimationEnd la devolución de llamada no se llama. 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.

1

Para cualquiera de tropezar con esta pregunta: Considere cambiar a utilizar el sistema de propiedad de animación en lugar http://developer.android.com/guide/topics/graphics/prop-animation.html

he tenido varios problemas con la vieja forma de animación de 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 quieres apoyar < 11 dispositivos de API, de Jake Wharton https://github.com/JakeWharton/NineOldAndroids es el camino a seguir

5

asegúrese de que que está utilizandoview.startAnimation(Animation) Y NOview.setAnimation(Animation). Esta simple confusión puede ser un problema.

-Cheers

0

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

Así que mi caso era: yo solía animatorSet y

  1. no había una única vista que podría llamar en clearAnimation,
  2. no estaba llamando mi animación de backgroundThread -que nunca se debe hacer que, Por cierto,

Como solución, que se llamaban animatorSet.end() justo antes animatorSet.start()

0

Cuando s inserta 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 la animación no se ejecuta por completo, la vista puede ser dejado en un estado incoherente (por ejemplo, la animación de los parámetros de diseño puede conducir a un factor de interpolación medio raro estar caído.Por esa razón, debe verificar al final de la devolución de llamada que la vista está en el estado deseado. Si no, simplemente configúralo manualmente.

0

hacerlo como belows

  1. animación haga última
  2. lo invocan dentro de un manejador de
  3. oyente debe crear una instancia de 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() { 
}