70 votes

L'animation Android n'est pas terminée dans onAnimationEnd

Il semble qu'un android animation n'est pas vraiment fini, quand la onAnimationEnd événement est déclenché même si animation.hasEnded est définie sur true.

Je veux mon avis, pour changer un fond dessiné sur la fin de l' ScaleAnimation qui il fait, mais vous pouvez clairement voir qu'il est changé quelques millisecondes avant la fin. Le problème, c'est qu'elle scintille, car le nouvel arrière-plan s'affiche (=est) mis à l'échelle pour un court laps de temps jusqu'à ce que l'animation est vraiment de finitions.

Est-il un moyen pour obtenir la vraie fin de l'animation ou tout simplement empêcher le nouveau fond d'être mis à l'échelle de cette courte période de temps?

Merci!!!!


//EDIT: je suis en utilisant un AnimationListener pour obtenir de 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
}

94voto

Soham Points 2911

Ici est le bug lié à ce problème http://code.google.com/p/android-misc-widgets/issues/detail?id=8

Cela dit en substance que l'onAnimationEnd méthode ne fonctionne pas vraiment bien quand un AnimationListener est attaché à une Animation

La solution de contournement est de l'écouter pour l'animation d'événements dans la vue dont vous avez été l'application à l'animation de Par exemple, si au départ vous étiez fixation de l'animation de l'auditeur à l'animation comme ceci

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

et puis en appliquant à l'animation d'une ImageView comme ceci

mImageView.startAnimation(mAnimation);

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

public class MyImageView extends ImageView {

puis remplacer l' onAnimationEnd méthode de la classe de la Vue et de fournir toutes les fonctionnalités

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

C'est la bonne solution de contournement pour ce problème, de fournir la fonctionnalité de la plus-riden Affichage -> onAnimationEnd méthode par opposition à la onAnimationEnd méthode de la AnimationListener attaché à l'Animation.

Cela fonctionne correctement et il n'y a plus aucun scintillement vers la fin de l'animation. Espérons que cette aide.

32voto

lucknow_rocks Points 211

Je devais résoudre ce problème en appelant clearAnimation () sur la vue animée dans onAnimationEnd , qui supprimait le scintillement. C'est étrange pourquoi quelqu'un devrait-il le faire, car callAnimationEnd n'aurait été appelé que si l'animation est déjà terminée. Mais je suppose que la réponse réside dans la profondeur de Framework sur la façon dont la vue / la mise en forme gère le rappel d’animation. Pour le moment, prenez-le comme une solution sans piratage, cela fonctionne.

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

6voto

Doigen Points 111

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

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

Après avoir appelé view.StartAnimation(animation) , et avant la prochaine étape de mon programme, j'ai ajouté un court délai qui sera suffisamment long pour laisser l'animation se terminer, mais suffisamment court pour que l'utilisateur ne puisse pas le remarquer:

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

2voto

Matt Points 1518

Pour une raison quelconque, le onAnimationStart fonctionne correctement, et le onAnimationEnd ne marche pas. Heres la façon dont je l'a fait à l'origine et ce que j'ai changé:

Tentative 1 (flicker): a) Déplacement de l'image à partir à 0px 80px b) Dans onAnimationEnd, définir l'image de l'emplacement de 80px

Tentative 2 (sans scintillement): a) Dans onAnimationStart, définir l'image de l'emplacement de 80px b) Déplacer l'image à partir d'-80px à 0px

L'espoir qui fait sens. Fondamentalement, je suis retourné, je l'ai fait

-1voto

chochim Points 464

Cela a fonctionné pour moi:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X