2

アニメーションの変換行列を取得して、アニメーション化されたビューの位置を計算したいと考えています。

Animation クラスには、ビューに適用される変換を取得するために使用できる getTransformation というメソッドがあるようです。

ただし、アニメーションを開始する前に getTransformation を使用すると、恒等行列を取得できます。そして、次のように使用すると:

public void onAnimationEnd(Animation animation) {
    Transformation t = new Transformation();
    animation.getTransformation(animation.getDuration(), t);
}

getTransformation が onAnimationEnd をトリガーするように見えるため (なぜ?)、プログラムは無限ループに入ります。

アニメーションの変換行列を取得するには、getTransformation をどのように使用すればよいですか? これを行う別の方法はありますか?

4

2 に答える 2

0

なぜなら、何らかの理由で、それがgetTransformationのコーディング方法だからです。

http://www.netmite.com/android/mydroid/1.5/frameworks/base/core/java/android/view/animation/Animation.java

hasEnded()をチェックして、アニメーションが完了したかどうかを確認できるようです。次のようなものを試してください。

public void onAnimationEnd(Animation animation)
{
   if ( animation.hasEnded() )
       return;

   Transformation t= new Transformation();
   animation.getTransformation(animation.getDuration(), t);
}
于 2010-08-17T16:55:55.603 に答える
0

前のアニメーションが完了した後に次のアニメーションの getTransformation() を実行したい場合にも、この問題に遭遇しました。その後、無限ループがスタックオーバーフローを引き起こします。

Android のソース コードの問題をGrepCodeから分析したところ、以下のコードで、場所呼び出しのみが trueに設定されるためgetTransformation()、無限ループを引き起こす問題は見つかりませんでし た。次回 を呼び出すと、 によってブロックされるはずですが、そうではありません。onAnimationEnd()mEndedgetTransformation()if(!mEnded)

    if (expired) {
        if (mRepeatCount == mRepeated) {
            if (!mEnded) {
                mEnded = true;   //this is not real!!!
                if (mListener != null) {
                    mListener.onAnimationEnd(this);
                }
            }
        } else {
            if (mRepeatCount > 0) {
                mRepeated++;
            }

            if (mRepeatMode == REVERSE) {
                mCycleFlip = !mCycleFlip;
            }

            mStartTime = -1;
            mMore = true;

            if (mListener != null) {
                mListener.onAnimationRepeat(this);
            }
        }
    }

このコード セグメントでは、grepcode が正しくありません。真実は、呼び出さeEnded = trueれた後に設定されることです:onAnimationEnd()

    if (!mEnded) {
            if (mListener != null) {
                mListener.onAnimationEnd(this);
            }
            //it happen after onAnimationEnd(). cancel() is also does as this
            mEnded = true; 
        }

これで、無限ループが発生する理由が説明できるはずです。animation.hasEnded()mEnded を true に設定することができなかったため、チェックしても役に立ちません。

この問題をハッキングする方法は次のとおりです。
リスナーにフラグを設定してガードします。

boolean needBlock = false;
public void onAnimationEnd(Animation animation)
{
   if ( needBlock ) return;

   needBlock = true;
   Transformation t= new Transformation();
   animation.getTransformation(animation.getDuration(), t);
}

AnimationListner をクリアします。必要に応じて、後で戻すことができます

public void onAnimationEnd(Animation animation)
{
   animation.setAnimationListener(null);
   Transformation t= new Transformation();
   animation.getTransformation(animation.getDuration(), t);
   animation.setAnimationListener(this);
}
于 2013-03-06T19:49:40.317 に答える