11

我正在做一些需要一个接一个播放大约 10 个动画的东西,但是在每个动画结束时需要检查一些条件,所以我不能使用动画集或 setStartDelay。

我发现在 Jelly Bean 上使用新方法很容易做到,其中的新方法是 withEndAction,而我正在做它作为实验,但现在我必须在具有 minSdk 10 的应用程序中实现它。

我正在使用九个旧 Android 并且效果很好,但是使用 setListner 非常困难,并且创建的代码难以维持 10 个连续动画。

所以我在想,创建一个继承自九个旧机器人的适配器,我可以添加执行 runnable 的 withEndAction 函数?

有人可以指导我如何做到这一点,有没有更好的方法呢?

谢谢

4

6 回答 6

26

我使用了 setListener

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        viewPropertyAnimator.setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                doSomething();
            }
        });
    } else {
        viewPropertyAnimator.withEndAction(new Runnable() {
            @Override
            public void run() {
                doSomething();
            }
        });
    }
于 2013-10-11T15:38:14.367 回答
7

您现在可以使用ViewCompat和附加您想要的任何动画。

ViewCompat.animate(yourView).scaleY(3).withEndAction(yourRunnable).start();
于 2016-11-15T04:39:20.093 回答
0

基本上,为了使您的代码更具可读性,您可以使用内置的AnimatorListenerAdapter将您从匿名内部类混乱中拯救出来。您甚至可以将其抽象化,使其看起来像withEndAction这样:

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Application;
import android.support.v4.view.ViewPropertyAnimatorListener;
import android.view.View;


public class AnimatorActionListener extends AnimatorListenerAdapter {

public enum ActionType {
    START, END;
}

final private ActionType type;
final private Runnable action;

public AnimatorActionListener(Runnable action, ActionType type) {
    this.action = action;
    this.type = type;
}

@Override
public void onAnimationEnd(Animator animation) {
    if (type == ActionType.END) {
        action.run();
    }
}

@Override
public void onAnimationStart(Animator animation) {
    if (type == ActionType.START) {
        action.run();
    }
}
}

然后用法变成:

 view.animate()./*...some parameters...*/.setListener(new AnimatorActionListener(new Runnable() {
        @Override
        public void run() {
            // do stuff
        }
    }, ActionType.END)); // or ActionType.START

而对于那些必须使用平台内置函数的人来说withStartAction, withEndAction,只需将SDK检查代码AnimatorActionListener也放入其中,以免客户端类杂乱无章。

于 2014-08-02T09:54:23.943 回答
0

我能想到2个选项:

  1. 使用外观模式创建自己的动画池(这可能需要很多工作)
  2. 从 ADT 获取源代码并进行修改。如果你找不到它,这里是:http: //pastebin.com/9nCPC4aR。将它(类似于ViewPropertyAnimatorCompat)复制到您自己的包中。该类似乎与其他 Android 的东西没有太多的耦合,所以应该按原样工作:)
  3. 更新:这是另一种选择,动画队列。类似于第一个想法,但更直截了当:

代码:

public class AnimationQueue extends LinkedList<Animation> implements
    AnimationListener {

private View mView;

public static AnimationQueue ready(Animation... animations) {
    AnimationQueue queue = new AnimationQueue();
    for (Animation animation : animations) {
        queue.add(animation);
    }
    return queue;
}

public AnimationQueue steady(View view) {
    mView = view;
    return this;
}

public void go() {
    Animation animation = poll();
    animation.setAnimationListener(this);
    mView.startAnimation(animation);
}

@Override public void onAnimationEnd(Animation animation) {
    go();
}

@Override public void onAnimationStart(Animation animation) {
}

@Override public void onAnimationRepeat(Animation animation) {
}

}

用法:

AnimationQueue.ready(anim1, anim2, anim3).steady(view).go();

干杯

于 2013-01-14T10:33:19.727 回答
0

我想我有更好的解决方案:

            view.animate().setDuration(2000).alpha(0);
            //timAnimDelay.purge();
            timAnimDelay.schedule(new TimerTask() {
                @Override
                public void run() {

                    // on UI thread
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // here animation
                        }
                    });
                }
            // delay start
            } , 2000);
            timAnimDelay.purge();
于 2013-05-31T13:21:06.707 回答
0

我的解决方案也使用了很棒的 Nineoldandroids

代替

starsBig[4].animate().rotation(3600).setDuration(2000).withEndAction(runnable)

我做了

animate(starsBig[4]).rotationBy(3600).setDuration(2010);
this.runOnUiThread(new Runnable() {
public void run() {
    for (int i = 0; i < 5; i++) {
        starReset(stars[i]);
        starReset(starsBig[i]);
    }
           }
});

它适用于一个动画

于 2013-01-17T18:15:01.057 回答