l'animation android n'est pas terminée dans onAnimationEnd

il semble qu'une animation android n'est pas vraiment terminée lorsque l'événement onAnimationEnd est déclenché bien que animation.hasEnded soit mis à true.

je veux mon avis, pour changer un fond dessiné sur la fin du ScaleAnimation dont il fait, mais vous pouvez clairement voir qu'il est changé quelques millisecondes avant la fin. Le problème est, qu'il clignote parce que le nouveau fond apparaît (=est) gradué pour un court laps de temps jusqu'à ce que l'animation se termine vraiment.

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

Merci!


//modifier: 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
}
65
demandé sur Adrian Cid Almaguer 2011-01-20 21:23:17

11 réponses

Voici Le bogue relatif à ce numéro http://code.google.com/p/android-misc-widgets/issues/detail?id=8

cela indique essentiellement que la méthode onAnimationEnd ne fonctionne pas vraiment bien quand un animateur D'animation est attaché à une Animation

la solution est d'écouter les événements d'animation dans la vue à laquelle vous appliquiez l'animation pour Par exemple, si au départ vous étiez fixation de la animateur d'animation à l'animation comme celle-ci

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

et puis appliquer à l'animation à une ImageView comme celle-ci

mImageView.startAnimation(mAnimation);

pour travailler autour de cette question, vous devez maintenant créer un ImageView personnalisé

public class MyImageView extends ImageView {

et puis outrepasser la méthode onAnimationEnd de la classe de vue et de fournir toutes les fonctionnalités il

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

il s'agit de la solution de rechange appropriée pour ce problème, fournir la fonctionnalité dans la vue over-riden - > méthode onAnimationEnd par opposition à la méthode onAnimationEnd de L'animateur 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.

91
répondu Soham 2014-02-20 21:43:20

j'étais capable de résoudre ceci en appelant clearAnimation () sur la vue étant animée à l'intérieur onAnimationEnd , qui a enlevé le clignotement C'est bizarre pourquoi quelqu'un devrait faire ça, car onAnimationEnd callback aurait dû être appelé seulement si l'animation était déjà terminée. Mais je suppose que la réponse réside dans la profondeur du cadre sur la façon dont view/layout gère le rappel d'animation. Pour l'instant, prends ça comme une solution sans piratage, ç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);
32
répondu lucknow_rocks 2011-04-12 21:03:22

j'ai eu un problème similaire et j'ai utilisé la solution de Soham avec custom view class.

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

après avoir appelé le view.StartAnimation(animation) , et avant la prochaine étape de mon programme, j'ai ajouté un court délai qui sera assez long pour laisser l'animation finir, mais assez court pour être inaperçu par l'utilisateur:

new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
           nextStepInMyProgram();
       }
     }, 200);// delay in milliseconds (200)
6
répondu Doigen 2013-09-08 11:58:00

j'ai eu le même problème et l'ai résolu en utilisant

view.clearAnimation();

avant

view.startAnimation(anim);
5
répondu savepopulation 2014-09-10 14:15:46

pour une raison quelconque, l'onAnimationStart fonctionne correctement, et l'onAnimationEnd ne fonctionne pas. Voici donc comment je l'ai fait à l'origine et ce que j'ai changé:

tentative 1 (Clignotant): A) déplacer l'image de 0px à 80px b) dans onAnimationEnd, définissez l'emplacement de l'image à 80px

tentative 2 (pas de clignotant): a) dans onAnimationStart, définissez l'emplacement de l'image à 80px B) déplacer l'image de-80px à 0px

l'Espoir qui fait sens. Fondamentalement, je suis retournée je l'ai fait

2
répondu Matt 2011-02-08 19:11:21

Essayez d'utiliser getAnimation() de votre objet:

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
            }
        });
}
1
répondu Butsaty 2016-06-09 20:19:12

une solution facile est d'ajouter une ligne à AnimationListener.onAnimationEnd() :

@Override 
public void onAnimationEnd(Animation a) {
    a.setAnimationListener(null);
    …
}
0
répondu Alex Cohn 2015-06-29 14:56:01

annimation peut également être arrêté sur la rotation de l'écran. dans ce cas onAnimationEnd() n'est pas appelée. mon 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);
0
répondu Oleg Khalidov 2015-07-31 09:42:22

j'ai eu ce problème parce que mon Animation n'a pas été démarré dans le fil principal. Il en est résulté un duration de 0. Cependant, le Animation a joué correctement - il a juste appelé onAnimationEnd() immédiatement après l'exécution.

0
répondu Ken Van Hoeylandt 2015-09-24 11:53:17

si vous utilisez repeat count comme infini, alors onAnimationEnd ne serait pas appelé. Vérifier la documentation lien

0
répondu sanjeeb 2018-03-28 10:19:04

cela a fonctionné pour moi:

@Override
public void onAnimationUpdate(ValueAnimator animation) {
    if (Float.compare(animation.getAnimatedFraction(),1.0f)) {
    // animation ended;
        //do stuff post animation
    }
}
-1
répondu chochim 2013-12-01 23:28:58