Android Animation one after other
I have two TranslateAnimations on a TextView and I want them to execute one after other. However, by using the code below, only the second one is executed.
How can I solve this?
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(anima开发者_如何学运维tion1);
Link them together with 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);
EDIT: Andy Boots answer below is the better answer imo.
Just set your first one like this and it'll start the other one, once the animation finishes:
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: The reason only your second animation is executed with your current code, is because it overrides the playing of the first animation (both actually are played, but you only see the latest one to start). If you do like I wrote, they will play sequentially instead of in parallel.
also you can do this by XML itself using android:startOffset
attribute , and there is an examble:
<?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>
There is one more approach to reach this goal which can be useful when you need to animate a lot of views one after another. You can use setStartOffset
method to set a delay before animation begins. So, if you know, how much time will take for your first animation to end, you can set this as a delay for your second animation. This is an example where I animated six ImageButtons
and six TextViews
below them one after another:
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 ++;
}
}
In my res/anim
folder I have a file, called fade.xml
with these contents:
<?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" />
Create an animation array and use method for creating 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);
Method:
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;
}
If you use code, you can call
Animation.setStartOffset()
to delay the second animation.
if you use xml you can android:ordering="sequentially"
property to make the two animations perform sequentially.
For simple animations, you can achieve this by using the animate()
and withEndAction()
functions, like so:
ImageView img = findViewById(R.id.imageView);
img.animate().rotation(180).alpha(0).setDuration(3000).withEndAction(new Runnable() {
@Override
public void run() {
ImageView img = findViewById(R.id.imageView);
img.animate().rotation(0).alpha(1).setDuration(2000);
}
});
AnimationDrawable
Running such animation is pretty straightforward in Android. In fact, there is a class in Android API just for this specific task called AnimationDrwable. AnimationDrawable is a set of images together.
Step1: Create AnimationDrwable
Step2: Load Animation Drawable into ImageView
step3: start the animation
Step 1: Create an XML and add all images like this.
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/cat_image_1" android:duration="200" />
<item android:drawable="@drawable/cat_image_2" android:duration="200" />
<item android:drawable="@drawable/cat_image_3" android:duration="200" />
</animation-list>
Step 2:
public void onCreate(Bundle savedInstanceState) {
//Step 2
ImageView myimage = (ImageView) findViewById(R.id.my_image);
myimage.setBackgroundResource(R.drawable.rocket_thrust);
//Step 3
AnimationDrawable catAnimation = (AnimationDrawable) rocketImage.getBackground();
catAnimation.start();
}
精彩评论