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 } }