J'ai deux TranslateAnimations sur un TextView et je veux qu'ils s'exécutent les uns après les autres. Cependant, en utilisant le code ci-dessous, seul le second est exécuté.
Comment puis-je résoudre ça?
TranslateAnimation animation = new TranslateAnimation(
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, -150.0f);
animation.setDuration(200);
wave.startAnimation(animation);
TranslateAnimation animation1 = new TranslateAnimation(
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 150.0f, Animation.ABSOLUTE, 0.0f);
animation1.setDuration(200);
wave.startAnimation(animation1);
EDIT: Andy Boots réponse ci-dessous est la meilleure réponse imo.
Définissez simplement votre première comme ceci et cela démarrera l’autre, une fois l’animation terminée:
animation.setAnimationListener(new 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) {
wave.startAnimation(animation1);
}
});
edit: la seule raison pour laquelle votre seconde animation est exécutée avec votre code actuel, c'est parce qu'elle annule le jeu de la première animation (les deux sont réellement joués, mais vous ne voyez que la dernière pour commencer). Si vous faites comme je l'ai écrit, ils joueront de manière séquentielle plutôt qu'en parallèle.
Liez-les ensemble avec Animation Set
AnimationSet as = new AnimationSet(true)
TranslateAnimation animation = new TranslateAnimation(
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, -150.0f);
animation.setDuration(200);
as.addAnimation(animation);
TranslateAnimation animation1 = new TranslateAnimation(
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 150.0f, Animation.ABSOLUTE, 0.0f);
animation1.setDuration(200);
animation1.setStartOffset(200);
as.addAnimation(animation1);
wave.startAnimation(as);
vous pouvez aussi le faire par XML lui-même en utilisant l'attribut Android:startOffset
, et voici un exemple:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android">
<scale
Android:duration="300"
Android:fromXScale="0%"
Android:fromYScale="0%"
Android:pivotX="50%"
Android:pivotY="50%"
Android:toXScale="100%"
Android:toYScale="100%" />
<alpha
Android:duration="300"
Android:fromAlpha="0"
Android:toAlpha=".5" />
<alpha
Android:duration="300"
Android:fromAlpha=".5"
Android:startOffset="300"
Android:toAlpha="1" />
</set>
Il existe une autre approche pour atteindre cet objectif qui peut être utile lorsque vous devez animer de nombreuses vues les unes après les autres. Vous pouvez utiliser la méthode setStartOffset
pour définir un délai avant le début de l'animation. Donc, si vous savez combien de temps il faudra pour que votre première animation se termine, vous pouvez définir cela comme un délai pour votre deuxième animation. Voici un exemple où j'ai animé six ImageButtons
et six TextViews
dessous les uns après les autres:
public void animateButtons() {
// An array of buttons
int[] imageButtonIds = {R.id.searchButton, R.id.favoriteButton, R.id.responseButton, R.id.articleButton, R.id.resumeButton, R.id.subscribeButton};
// Array of textViews
int[] textViewIds = {R.id.searchTextView, R.id.favoriteTextView, R.id.responseTextView, R.id.articleTextView, R.id.resumeTextView, R.id.subscribeTextView};
int i = 1;
for (int viewId : imageButtonIds) {
ImageButton imageButton = (ImageButton) findViewById(viewId);
// Animation from a file fade.xml in folder res/anim
Animation fadeAnimation = AnimationUtils.loadAnimation(this, R.anim.fade);
// Delay for each animation is 100 ms bigger than for previous one
fadeAnimation.setStartOffset(i * 100);
imageButton.startAnimation(fadeAnimation);
// The same animation is for textViews
int textViewId = textViewIds[i-1];
TextView textView = (TextView) findViewById(textViewId);
textView.startAnimation(fadeAnimation);
i ++;
}
}
Dans mon dossier res/anim
, j'ai un fichier, appelé fade.xml
avec le contenu suivant:
<?xml version="1.0" encoding="utf-8"?>
<!-- Fade animation with 500 ms duration -->
<alpha xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:interpolator="@Android:anim/accelerate_decelerate_interpolator"
Android:fromAlpha="0.0" Android:toAlpha="1.0"
Android:duration="500" />
Créez un tableau d'animation et utilisez une méthode pour créer AnimationSet.
Animation[] animations = {
getScaleAnimation(0.4f, 1.3f, 2000),
getScaleAnimation(1.3f, 1.0f, 500),
getScaleAnimation(0.4f, 1.3f, 1000),
getScaleAnimation(1.3f, 1.0f, 3000),
getScaleAnimation(0.4f, 1.3f, 500),
getScaleAnimation(1.3f, 1.0f, 1700),
getScaleAnimation(0.4f, 1.3f, 2100),
getScaleAnimation(1.3f, 1.0f, 3400)
};
AnimationSet animationSet = addAnimationAr(animations);
view.startAnimation(animationSet);
Méthode:
public static AnimationSet addAnimationAr(Animation[] animations) {
AnimationSet animationSet = new AnimationSet(false);
long totalAnimationDuration = 0;
for (int i = 0; i < animations.length; i++) {
Animation a = animations[i];
a.setStartOffset(totalAnimationDuration);
totalAnimationDuration += a.getDuration();
animationSet.addAnimation(a);
}
return animationSet;
}
Si vous utilisez du code, vous pouvez appeler
Animation.setStartOffset()
pour retarder la deuxième animation.
si vous utilisez xml, vous pouvez utiliser la propriété Android:ordering="sequentially"
pour que les deux animations s'exécutent de manière séquentielle.