69

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

ビューの最後に描画可能な背景を変更したいのですが、終了する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
}
4

12 に答える 12

94

この問題に関連する実際のバグは次のとおりですhttp://code.google.com/p/android-misc-widgets/issues/detail?id=8

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

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

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

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

mImageView.startAnimation(mAnimation);

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

public class MyImageView extends ImageView {

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

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

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

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

于 2011-02-24T21:05:55.510 に答える
32

onAnimationEnd内でアニメーション化されているビューで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);
于 2011-04-12T20:54:42.970 に答える
6

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

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

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

new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
           nextStepInMyProgram();
       }
     }, 200);// delay in milliseconds (200)
于 2013-09-08T11:58:00.180 に答える
6

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

view.clearAnimation();

view.startAnimation(anim);
于 2014-09-10T14:15:46.543 に答える
2

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

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

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

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

于 2011-02-08T19:11:21.197 に答える
2

オブジェクトから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
            }
        });
}
于 2016-06-09T20:19:12.940 に答える
1

画面の回転時にアニメーションを停止することもできます。この場合、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);
于 2015-07-31T09:42:22.653 に答える
0

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

@Override 
public void onAnimationEnd(Animation a) {
    a.setAnimationListener(null);
    …
}
于 2015-06-29T14:18:20.497 に答える
0

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

于 2015-09-24T11:53:17.933 に答える
0

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

于 2018-03-28T10:19:04.170 に答える
0

を使用setUpdateListenerして、アニメーションの進行状況の現在の部分を確認し、それに応じて行動することもできます。

これは、最終的にビューがレイアウトから消えるフェードアウトアニメーションのKotlinの例です。

view.animate()
        .alpha(0f)
        .setDuration(duration)
        .setUpdateListener { animation ->
            if (animation.animatedFraction > 0.99f) {
                view.visibility = View.GONE
            }
        }
        .start()
于 2020-09-23T10:04:08.177 に答える
-1

これは私のために働いた:

@Override
public void onAnimationUpdate(ValueAnimator animation) {
    if (Float.compare(animation.getAnimatedFraction(),1.0f)) {
    // animation ended;
        //do stuff post animation
    }
}
于 2013-10-30T14:08:56.093 に答える