onAnimationEnd ne s’appelle pas, onAnimationStart fonctionne bien

J’ai un ScrollView dans le PopupWindow. J’anime des contenus ScrollView en utilisant TranslateAnimation.

Lorsque l’animation démarre, l’écouteur onAnimationStart est appelé, mais onAnimationEnd n’est pas appelé. Des idées ?

Disposition :

     ...    

Code d’animation:

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

Mise à jour : J’ai vérifié que le onAnimationEnd est appelé mais il est appelé après un certain délai (à condition de ne pas démarrer la nouvelle animation pendant ce temps).

    AnimationEnd n’est pas fiable. Si vous ne souhaitez pas réécrire votre code avec des vues personnalisées qui remplacent OnAnimationEnd, utilisez postDelayed .

    Voici un exemple de code:

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

    Bien que cela puisse paraître moche, je peux vous garantir que c’est très fiable. Je l’utilise pour les ListViews qui insèrent de nouvelles lignes tout en supprimant avec animation les autres lignes. Le fait de tester un auditeur avec AnimationEnd s’est avéré peu fiable. Parfois, AnimationEnd n’a jamais été déclenché. Vous voudrez peut-être réappliquer toute transformation dans la fonction postDelayed au cas où l’animation ne postDelayed pas complètement terminée, mais cela dépend vraiment du type d’animation que vous utilisez.

    Après je ne me souviens plus comment les publications peuvent être lues et les jours passés à trouver une solution à ce problème, j’ai découvert que si l’object à déplacer ne se trouvait pas dans la région Screen (par exemple, appelé. L’animation échoue probablement juste après le démarrage (la méthode de démarrage est appelée, j’ai codé un écouteur) mais rien n’est écrit dans logcat. Peut-être que ce n’est pas exactement votre cas, mais cela a finalement résolu mon problème et j’espère que cela vous aidera aussi.

    Assurez-vous que vous view.startAnimation(Animation) AND NOT view.setAnimation(Animation) . Cette simple confusion peut être un problème.

    De même, lorsque vous utilisez des animations, n’oubliez pas de setFillAfter() sur true .

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

    Si fillAfter est vrai, la transformation effectuée par cette animation persistera à la fin. La valeur par défaut est false si elle n’est pas définie. Notez que cela s’applique lorsque vous utilisez un AnimationSet pour enchaîner les animations. La transformation n’est pas appliquée avant que AnimationSet lui-même ne démarre.

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

    Pour ceux qui tombent sur cette question: envisagez de passer à l’utilisation du système d’animation de propriété à la place de http://developer.android.com/guide/topics/graphics/prop-animation.html

    J’ai eu plusieurs problèmes avec l’ancienne méthode d’animation d’un fondu entrant / sortant sur une vue (via AlphaAnimation). OnAnimationEnd n’était pas appelé etc. Avec l’animation de propriété, tous ces problèmes ont été résolus.

    Si vous voulez prendre en charge les périphériques API <11, https://github.com/JakeWharton/NineOldAndroids de Jake Wharton est la voie à suivre

    N’êtes-vous pas en train de mettre en place une autre animation avant celle que vous attendez?

    Sans contexte, il est difficile de comprendre si c’est quelque chose comme ça … mais c’est probablement l’une des seules choses qui le causerait.

    Je suppose que l’on l’appelle après un certain temps, car vous utilisez setDuration pour l’animation et y passez 1000 ms. Il suffit de passer 0 et il ne faudra pas du temps pour être appelé.

    Le délai est probablement dû à l’anim.setDuration (1000) ou si vous le faites sur un thread, probablement à cause du changement de contexte. Essayez de manipuler le délai et voyez si vous remarquez une différence.

    Essayez d’utiliser overridePendingAnimation (int, int). ie overridePendingAnimation (0,0)

    Il remplacera votre animation par défaut et vous pourrez ensuite définir votre propre animation. En appelant la méthode startAnimation en utilisant l’object de View.

    Voici mon exemple de code. Ne sais pas si cela vous sera utile ou non.

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

    J’ai essayé votre code, cela fonctionne bien au démarrage OnAnimation et inAmimationEnd aussi, après que la durée signifie après que l’animation terminée, on appelleAnimationEnd, donc votre code fonctionne 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); 

    Il y a peut-être encore quelqu’un qui a ce problème et qui n’a pas trouvé de solution – même si elle lit beaucoup de réponses stackoverflow – comme moi!

    Donc mon cas était: j’ai utilisé animatorSet et

    1. il n’y avait pas une seule vue que je pourrais appeler clearAnimation sur,
    2. Je n’appelais pas mon animation de backgroundThread – ce que vous ne devriez jamais faire, btw-

    Comme solution, j’ai appelé animatorSet.end() juste avant animatorSet.start()

    Lorsque vous lancez une commande d’animation dans une vue partiellement hors écran, l’animation démarre et onStartListener est appelé, mais l’animation ne s’exécute pas complètement (elle est en quelque sorte interrompue au milieu). Je suppose que, comme la vue est hors écran, elle est annulée et donc onFinish n’est pas appelée. Pour contourner ce problème, j’ai créé mon propre écouteur d’animation qui commence par un gestionnaire et utilise postDelayed pour notifier l’utilisateur de l’événement de fin d’animation. À 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) } } 

    Veuillez noter que si l’animation ne s’exécute pas complètement, la vue peut restr incohérente (par exemple, l’animation de parameters de disposition peut entraîner la suppression d’un facteur d’interpolateur intermédiaire étrange. Pour cette raison, vous devez vérifier à le rappel de fin que la vue est à l’état voulu, sinon définissez-la manuellement.

    Faites-le comme les belows

    1. faire l’animation finale
    2. invoquez-le dans un gestionnaire
    3. l’auditeur devrait être instancié une fois.
    4. animation claire.

    par exemple 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() { } 

    Où commencez-vous votre animation? Si onCreate, c’est faux. Essayez de le faire dans onResume.