web-dev-qa-db-ja.com

androidアニメーションはonAnimationEndで終了していません

onAnimationEndイベントが発生したときにAndroidアニメーションが本当に終了しないようですanimation.hasEndedはtrueに設定されます。

私のビューは、ScaleAnimationの最後にあるドローアブルの背景を変更したいのですが、終了する前に数ミリ秒変更されていることがはっきりとわかります。問題は、アニメーションが実際に終了するまで、新しい背景が短時間スケーリングされるためにちらつくことです。

アニメーションの実際の終わりを取得する方法、またはこの短い期間に新しい背景が拡大されないようにする方法はありますか?

ありがとうございました!


//編集:AnimationListenerを使用して、次の呼び出しを取得しています。

    @Override
public void onAnimationEnd(Animation animation)
{
    View view = (MyView) ((ExtendedScaleAnimation) animation).getView();

    view.clearAnimation();
    view.requestLayout();
    view.refreshBackground(); // <-- this is where the background gets changed
}
65
ShadowMare

この問題に関連する実際のバグを次に示します http://code.google.com/p/Android-misc-widgets/issues/detail?id=8

これは基本的に、AnimationListenerがAnimationにアタッチされている場合、onAnimationEndメソッドが実際にうまく機能しないことを示しています。

回避策は、アニメーションを適用するビューでアニメーションイベントをリッスンすることです。たとえば、最初にこのようなアニメーションにアニメーションリスナーをアタッチした場合

mAnimation.setAnimationListener(new AnimationListener() {
    @Override
    public void onAnimationEnd(Animation arg0) {
        //Functionality here
    }
});

そして、このようなImageViewにアニメーションを適用します

mImageView.startAnimation(mAnimation);

この問題を回避するには、カスタムImageViewを作成する必要があります

public class MyImageView extends ImageView {

そして、ViewクラスのonAnimationEndメソッドをオーバーライドし、そこですべての機能を提供します

@Override
protected void onAnimationEnd() {
    super.onAnimationEnd();
    //Functionality here
}

これがこの問題の適切な回避策です。アニメーションにアタッチされたAnimationListenerのonAnimationEndメソッドではなく、オーバーライドされたView-> onAnimationEndメソッドで機能を提供します。

これは適切に機能し、アニメーションの終わりにちらつきはなくなりました。お役に立てれば。

91
Soham

内部でアニメーション化されているビューでclearAnimation()を呼び出してこれを解決するために私は安倍していましたonAnimationEndコールバックは、アニメーションが既に終了している場合にのみ呼び出す必要があります。しかし、答えは、ビュー/レイアウトがアニメーションコールバックを処理する方法に関するフレームワークの深さにあると思います。現時点では、ハッキングのないソリューションと考えてください。

        animation.setAnimationListener(new AnimationListener() {

        public void onAnimationEnd(Animation anim) {
            innerView.clearAnimation();   // to get rid of flicker at end of animation

            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams
            (innerBlockContainer.getWidth(), innerBlockContainer.getHeight());

            /* Update lp margin, left/top to update layout after end of Translation */
            ViewGroup parent_ofInnerView = (ViewGroup)innerView.getParent();
            vp.updateViewLayout(innerBlockContainer, lp);

        }

        public void onAnimationRepeat(Animation arg0) {}

        public void onAnimationStart(Animation arg0) {
        }

    });

     innerView.startAnimation(animation);
32
lucknow_rocks

同様の問題があり、カスタムビュークラスでSohamのソリューションを使用しました。

それはうまくいきましたが、最後に、私のために働いたより簡単な解決策を見つけました。

view.StartAnimation(animation)を呼び出した後、プログラムの次のステップの前に、アニメーションを終了させるのに十分な長さであるが、ユーザーが気付かないほど短い短い遅延を追加しました。

new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
           nextStepInMyProgram();
       }
     }, 200);// delay in milliseconds (200)
6
Doigen

私は同じ問題を抱えていて、それを使用して解決しました

view.clearAnimation();

view.startAnimation(anim);
5
savepopulation

何らかの理由で、onAnimationStartは適切に機能し、onAnimationEndは機能しません。だから私が最初にそれをやった方法と私が変更したことはここにあります:

試行1(ちらつき):a)画像を0pxから80pxに移動しますb)onAnimationEndで、画像の場所を80pxに設定します

試行2(ちらつきなし):a)onAnimationStartで、画像の場所を80pxに設定しますb)画像を-80pxから0pxに移動します

それが理にかなったことを願っています。基本的に私はそれをやった方法をひっくり返した

2
Matt

オブジェクトからgetAnimation()を使用してみてください。

public void onShowListBtnClick(View view)
    {
        rightPanel.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_left));

        rightPanel.getAnimation().setAnimationListener(new Animation.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) {
                // write your code here
            }
        });
}
2
Butsaty

画面の回転でアニメーションを停止することもできます。この場合、onAnimationEnd()は呼び出されていません。私の回避策:

 animation.setDuration(animationDuration);
 animation.setAnimationListener(new AnimationListenerAdapter() {...});
 view.startAnimation(animation);
 handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if(!animation.hasEnded()) {
                    // here you can handle this case
                }
            }
        }, animationDuration + 100);
1
Oleg Khalidov

繰り返しカウントを無限として使用している場合、onAnimationEndは呼び出されません。ドキュメントを確認してください link

0
sanjeeb

Animationがメインスレッドで開始されなかったため、この問題が発生しました。これにより、durationは0になりました。ただし、Animationは正しく再生されました。実行直後にonAnimationEnd()を呼び出しただけです。

0

簡単な修正方法は、1行をAnimationListener.onAnimationEnd()に追加することです。

@Override 
public void onAnimationEnd(Animation a) {
    a.setAnimationListener(null);
    …
}
0
Alex Cohn