l’animation Android n’est pas terminée dans onAnimationEnd

Il semble qu’une animation Android ne soit pas vraiment terminée lorsque l’événement onAnimationEnd est déclenché, bien que animation.hasEnded soit défini sur true.

Je veux que mon sharepoint vue change son arrière-plan à la fin de son ScaleAnimation , mais vous pouvez voir clairement qu’il a été modifié quelques millisecondes avant qu’il ne soit fini. Le problème est qu’il clignote parce que le nouvel arrière-plan apparaît (= est) mis à l’échelle pendant une courte période jusqu’à ce que l’animation se termine vraiment.

Y a-t-il un moyen d’obtenir la fin réelle de l’animation ou d’empêcher le nouvel arrière-plan d’être mis à l’échelle cette courte période de temps?

Je vous remercie!


// EDIT: J’utilise un AnimationListener pour obtenir l’appel suivant:

  @Override public void onAnimationEnd(Animation animation) { View view = (MyView) ((ExtendedScaleAnimation) animation).getView(); view.clearAnimation(); view.requestLayout(); view.refreshBackground(); // <-- this is where the background gets changed } 

Voici le bogue réel lié à ce problème: http://code.google.com/p/android-misc-widgets/issues/detail?id=8

Cela indique essentiellement que la méthode onAnimationEnd ne fonctionne pas correctement lorsqu’un AnimationListener est attaché à une animation.

La solution de contournement consiste à écouter les événements d’animation dans la vue à laquelle vous appliquez l’animation. Par exemple, si vous attachez initialement le programme d’écoute d’animation à cette animation

 mAnimation.setAnimationListener(new AnimationListener() { @Override public void onAnimationEnd(Animation arg0) { //Functionality here } }); 

et ensuite appliquer à l’animation à une image comme celle-ci

 mImageView.startAnimation(mAnimation); 

Pour contourner ce problème, vous devez maintenant créer un ImageView personnalisé

 public class MyImageView extends ImageView { 

puis remplacer la méthode onAnimationEnd de la classe View et fournir toutes les fonctionnalités

 @Override protected void onAnimationEnd() { super.onAnimationEnd(); //Functionality here } 

Ceci est la solution de contournement appropriée pour ce problème, fournissez la fonctionnalité dans la méthode View-> onAnimationEnd over-riden par opposition à la méthode onAnimationEnd de AnimationListener attaché à l’animation.

Cela fonctionne correctement et il n’y a plus de scintillement vers la fin de l’animation. J’espère que cela t’aides.

J’ai été obligé de résoudre ce problème en appelant clearAnimation () sur la vue animée à l’intérieur de onAnimationEnd , qui a enlevé le scintillement. C’est étrange pourquoi quiconque aurait à le faire, car le rappel surAnimationEnd aurait dû être appelé seulement Mais je suppose que la réponse réside dans la profondeur du Framework sur la façon dont les vues / agencements traitent les rappels d’animation. Pour l’instant, prenez-le comme une solution sans hack, ça marche.

  animation.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation anim) { innerView.clearAnimation(); // to get rid of flicker at end of animation RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams (innerBlockContainer.getWidth(), innerBlockContainer.getHeight()); /* Update lp margin, left/top to update layout after end of Translation */ ViewGroup parent_ofInnerView = (ViewGroup)innerView.getParent(); vp.updateViewLayout(innerBlockContainer, lp); } public void onAnimationRepeat(Animation arg0) {} public void onAnimationStart(Animation arg0) { } }); innerView.startAnimation(animation); 

J’ai eu un problème similaire et j’ai utilisé la solution de Soham avec une classe de vue personnalisée.

Cela a bien fonctionné, mais à la fin, j’ai trouvé une solution plus simple qui fonctionnait pour moi.

Après avoir appelé view.StartAnimation(animation) , et avant la prochaine étape de mon programme, j’ai ajouté un court délai suffisamment long pour permettre à l’animation de se terminer, mais suffisamment courte pour que l’utilisateur view.StartAnimation(animation) la view.StartAnimation(animation) :

 new Handler().postDelayed(new Runnable() { @Override public void run() { nextStepInMyProgram(); } }, 200);// delay in milliseconds (200) 

J’ai eu le même problème et résolu en utilisant

 view.clearAnimation(); 

avant

 view.startAnimation(anim); 

Pour une raison quelconque, onAnimationStart fonctionne correctement, et onAnimationEnd ne fonctionne pas. Alors voici comment je l’ai fait à l’origine et ce que j’ai changé:

Tentative 1 (scintillement): a) Déplacez l’image de 0px à 80px b) Dans onAnimationEnd, définissez la position de l’image sur 80px

Tentative 2 (pas de scintillement): a) Dans onAnimationStart, définissez la position de l’image sur 80px b) Déplacez l’image de -80px à 0px

J’espère que c’était logique. Fondamentalement, j’ai renversé la façon dont je l’ai fait

Essayez d’utiliser getAnimation () depuis votre object:

 public void onShowListBtnClick(View view) { rightPanel.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_left)); rightPanel.getAnimation().setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // write your code here } }); } 

Une solution simple consiste à append une ligne à AnimationListener.onAnimationEnd() :

 @Override public void onAnimationEnd(Animation a) { a.setAnimationListener(null); … } 

L’annulation peut également être interrompue lors de la rotation de l’écran. Dans ce cas, onAnimationEnd () n’est pas appelée. ma solution de contournement:

  animation.setDuration(animationDuration); animation.setAnimationListener(new AnimationListenerAdapter() {...}); view.startAnimation(animation); handler.postDelayed(new Runnable() { @Override public void run() { if(!animation.hasEnded()) { // here you can handle this case } } }, animationDuration + 100); 

J’ai eu ce problème parce que mon Animation n’a pas été lancée dans le thread principal. Cela a abouti à une duration de 0. Cependant, l’ Animation a bien fonctionné – elle a simplement appelé onAnimationEnd() immédiatement après l’exécution.

Si vous utilisez le nombre de répétitions comme infini, onAnimationEnd ne sera pas appelé. Vérifiez le lien de documentation

Cela a fonctionné pour moi:

 @Override public void onAnimationUpdate(ValueAnimator animation) { if (Float.compare(animation.getAnimatedFraction(),1.0f)) { // animation ended; //do stuff post animation } }