2

我遇到了一个奇怪的行为。如果我从 开始AnimationDrawablestart()那么在动画完成后,方法isRunning()仍然会返回 true。它是“一次性”动画,没有循环播放。

这是一个示例代码:

public class MyActivity extends Activity {
    private AnimationDrawable cartoon;
    private ImageView iv;
    private BitmapDrawable frame0, frame1;
    private final int sleep=1000;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        cartoon = new AnimationDrawable();
        cartoon.setOneShot(true);
        frame0 = new BitmapDrawable(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.gridx0));
        frame1 = new BitmapDrawable(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.gridx1));
    }

    @Override
    protected void onStart() {
        super.onStart();
        if(iv==null) iv = (ImageView) findViewById(R.id.imageView);
        cartoon.addFrame(frame0, sleep);
        cartoon.addFrame(frame1, sleep);
        iv.setImageDrawable(cartoon);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(cartoon.isRunning()) Log.d("AnimationTest", "Animation already started");
        else cartoon.start();
        return true;
    }
}

这是输出:

02-22 14:18:42.187: DEBUG/AnimationTest(2043): Animation already started
02-22 14:18:52.093: DEBUG/AnimationTest(2043): Animation already started
02-22 14:18:52.166: DEBUG/AnimationTest(2043): Animation already started
...and so on.

所以动画第一次运行,然后isRunning将永远返回 true。 我还发现发布到 code.google.com 的类似问题,但没有任何评论就关闭了

我的问题是:

  1. 有真正的错误还是我误解了什么?
  2. 我怎么知道什么时候AnimationDrawable完成?
4

4 回答 4

1

尝试扩展AnimationDrawable,声明您自己的布尔字段,该字段将用作标志。覆盖isRunning()并返回布尔字段。根据您的类动画侦听器(开始、重复、结束)更改标志。:)

于 2013-02-22T15:02:08.007 回答
1

看了源码后,我只能得出结论,设置为oneshot就是真正oneshot动画,不再赘述。至少,不是没有stop()先打电话。

如果您stop()在完成后调用,那么下一次调用就start()可以正常工作(至少在我的测试中)。你如何打电话stop()取决于你,但你可以安排一个计时器在你打电话时总持续时间过去后运行它start()。在这个类中没有回调确实有点糟糕。

如果您将经常使用此机制,则可能值得扩展AnimationDrawable以为其提供回调。如果你这样做了,你应该把它贴在某个地方,以便将来对你自己和其他人更容易。

于 2013-02-22T16:01:04.030 回答
0

处理动画结束的方法是计算总动画的持续时间并在持续时间到期后发送事件。

    private AnimationDrawable timerAnimation;

...

private void startTimerAnimation() {
    int timerAnimationDuration = calcTimerAnimationDuration();
    timerAnimation.start();
    timerAnimationEndHandler.sendEmptyMessageDelayed(0, timerAnimationDuration);
}


private int calcTimerAnimationDuration() {
    int total = 0;
    for (int i = 0; i < timerAnimation.getNumberOfFrames(); i++) {
        total += timerAnimation.getDuration(i);
    }
    return total;
}


private Handler timerAnimationEndHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        onTimerAnimatonFinished();
};
于 2015-02-11T08:17:16.977 回答
-1

如果您尝试:

    @Override
public boolean onTouchEvent(MotionEvent event) {
    if(cartoon.isRunning()){
      Log.d("AnimationTest", "Animation already started");
      return false;
   }else{
       cartoon.start();
      return true;
    }

}
于 2013-02-22T14:54:38.013 回答