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 souhaite que mon point de vue change de fond à la fin de la variable ScaleAnimation
, ce qui est le cas, mais vous pouvez voir clairement que la modification est effectuée quelques millisecondes avant la fin. Le problème est qu'il scintille car le nouvel arrière-plan apparaît (= est) mis à l'échelle pendant une courte période, jusqu'à la fin de l'animation.
Existe-t-il un moyen d’obtenir la fin réelle de l’animation ou simplement d’empêcher que le nouvel arrière-plan ne soit redimensionné pendant cette courte période?
Je vous remercie!
// EDIT: J'utilise une 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 actuel 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 vraiment bien lorsqu'un AnimationListener est attaché à une Animation.
La solution de contournement consiste à écouter les événements d'animation de la vue à laquelle vous appliquiez l'animation à Par exemple, si vous attachez initialement l'écouteur d'animation à l'animation comme celle-ci.
mAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation arg0) {
//Functionality here
}
});
puis appliquer à l'animation à un ImageView comme celui-ci
mImageView.startAnimation(mAnimation);
Pour contourner ce problème, vous devez maintenant créer un ImageView personnalisé.
public class MyImageView extends ImageView {
puis substituez la méthode onAnimationEnd
de la classe View et fournissez toutes les fonctionnalités
@Override
protected void onAnimationEnd() {
super.onAnimationEnd();
//Functionality here
}
Il s'agit de la solution de contournement appropriée pour ce problème. Fournissez les fonctionnalités de la méthode View-> onAnimationEnd trop ridée, par opposition à la méthode onAnimationEnd de l'AnimationListener attachée à 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.
Je devais résoudre ce problème en appelant clearAnimation () sur la vue animée à l'intérieur de onAnimationEnd , qui a supprimé le scintillement. é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 l’instant, considérez-la comme une solution sans hack, qui 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);
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 l'étape suivante 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)
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 et ce que j’ai changé:
Tentative 1 (scintillement): A) Déplacez l'image de 0px à 80px B. Dans onAnimationEnd, définissez l'emplacement de l'image sur 80px
Tentative 2 (pas de scintillement): A) Dans onAnimationStart, définissez l'emplacement de l'image sur 80px B) Déplacez l'image de -80px à 0px
J'espère que cela avait du sens. Fondamentalement, j'ai inversé la façon dont je l'ai fait
Essayez d’utiliser getAnimation () à partir 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
}
});
}
Si vous utilisez le nombre de répétitions comme infini, onAnimationEnd ne sera pas appelée. Consultez la documentation link
l'animation peut également être arrêtée lors de la rotation de l'écran. dans ce cas, onAnimationEnd () n'est pas appelé. 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 ma Animation
n'a pas été démarrée dans le fil principal . Cela a entraîné une duration
de 0 . Cependant, la Animation
a été lue correctement - elle a juste appelé onAnimationEnd()
immédiatement après l'exécution.
Une solution simple consiste à ajouter une ligne àAnimationListener.onAnimationEnd()
:
@Override
public void onAnimationEnd(Animation a) {
a.setAnimationListener(null);
…
}