安卓动画依次播放

25

我在一个TextView上有两个TranslateAnimations,我希望它们一个接着一个地执行。然而,使用下面的代码时,只有第二个动画会被执行。

我该如何解决这个问题?

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

你尝试过使用AnimationSet吗? - kAvEh
未正常工作,請更新。 - HandyPawan
8个回答

61

使用 动画集合 将它们链接在一起。

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

4
太棒了。然而,这似乎只为一个对象序列化动画。如果您需要为不同的对象序列化动画,则必须使用不同的方法。 - peter_the_oak
这对我有用,但顺序错误,我先放的动画变成了第二个,如何解决? - underfilho

36

编辑:在我看来,下面Andy Boots的回答更好。


只需像这样设置您的第一个动画,它将在动画完成后启动另一个动画:

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

        }
    });

编辑:你当前代码中只有第二个动画被执行的原因是,它覆盖了第一个动画的播放(实际上两个动画都在播放,但你只看到最后一个开始的)。如果按照我所写的那样做,它们将会依次播放而不是同时播放。


试了一下,它按照我想要的方式工作了...但只是好奇,有没有其他更好的方法来做到这一点?谢谢。 - amithgc
谢谢。它正是我正在寻找的那个。. . . - user644458
10
“just set ur flirst one leik dis n' it'll start teh” - 哎呀,去上学吧 :) 翻译:将你的第一个设定像这样,它就会开始了。——哎呀...去上学吧 :) - Ricky
你能帮忙解决http://stackoverflow.com/questions/18899280/multiple-xml-animation-is-not-working@pgsandstrom吗? - Si8

12

你还可以通过 XML 自身使用 android:startOffset 属性来实现此操作,这里有一个例子:

<?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>

8

还有一种方法可以实现这个目标,当你需要依次动画许多视图时,这种方法非常有用。你可以使用setStartOffset方法在动画开始之前设置延迟。所以,如果你知道第一个动画需要多长时间才能结束,你可以将其设置为第二个动画的延迟时间。以下是我依次动画六个ImageButtons和下面的六个TextViews的示例:

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 ++;
    }
}

在我的res/anim文件夹中有一个名为fade.xml的文件,其内容如下:
<?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" />

没起作用 |-) fadeAnimation.setStartOffset 改变了根动画。有什么解决办法吗? - Solivan

2
创建一个动画数组并使用方法创建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);

方法:

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

1
如果你使用代码,可以调用:

Animation.setStartOffset() 

延迟第二个动画。

如果您使用 xml,则可以使用 android:ordering="sequentially" 属性使两个动画按顺序执行。


1

对于简单的动画,您可以使用animate()withEndAction()函数来实现,如下所示:

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

好主意!我尝试使用 it.animate().yBy(-10F).withEndAction { it.animate().yBy(10F) } 来实现“跳跃”,如果你不断点击它,它就会飞到月球上去。我想我必须硬编码 y 值吗? - xjcl

0

AnimationDrawable

在Android中运行此类动画非常简单。实际上,Android API中有一个专门用于此特定任务的类,称为AnimationDrwable。 AnimationDrawable是一组图像。

步骤1:创建AnimationDrwable
步骤2:将Animation Drawable加载到ImageView中
步骤3:启动动画

步骤1: 创建XML并添加所有图像,如下所示。

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

步骤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();

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接