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

ソースを見てみると、ワンショットに設定すると、それが本当にワンショットアニメーションであり、繰り返しがないという結論に達することができます。少なくとも、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 に答える