web-dev-qa-db-ja.com

onAnimationEndが呼び出されず、onAnimationStartは正常に動作します

PopupWindowにScrollViewがあります。 TranslateAnimationを使用してScrollViewコンテンツをアニメーション化します。

アニメーションが開始されると、onAnimationStartリスナーが呼び出されますが、onAnimationEndは呼び出されません。何か案は ?

レイアウト :

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
   xmlns:Android="http://schemas.Android.com/apk/res/Android"
   Android:background="@drawable/popup_window_bg"
   Android:layout_width="match_parent"
   Android:layout_height="wrap_content">
  <View
     Android:layout_width="@dimen/toolbar_padding_left"
     Android:layout_height="@dimen/toolbar_height"/>
  <ScrollView
     xmlns:Android="http://schemas.Android.com/apk/res/Android"
     Android:id="@+web/toolbar"
     Android:layout_width="wrap_content"
     Android:layout_height="wrap_content"
     Android:scrollbars="none"
     Android:visibility="invisible">
    <LinearLayout
       Android:layout_width="match_parent"
       Android:layout_height="wrap_content"
       Android:orientation="vertical">

       ...

    </LinearLayout>
  </ScrollView>
</LinearLayout>

アニメーションコード:

mToolbar = mPopupContents.findViewById( R.web.toolbar );
TranslateAnimation anim =
    new TranslateAnimation(0, 0, -60, 0);
anim.setDuration(1000);
anim.setAnimationListener(new Animation.AnimationListener() {
        public void onAnimationStart(Animation a) {
            Log.d(LOGTAG, "---- animation start listener called"  );
        }
        public void onAnimationRepeat(Animation a) {}
        public void onAnimationEnd(Animation a) {
            Log.d(LOGTAG, "---- animation end listener called"  );
        }
    });
mToolbar.startAnimation(anim);

更新:onAnimationEndが呼び出されることを確認しましたが、しばらくしてから呼び出されます(その間に新しいアニメーションを開始しない場合)。

44
Karan

AnimationEndは信頼できません。 OnAnimationEndをオーバーライドするカスタムビューでコードを書き直したくない場合は、postDelayedを使用します。

コードの例を次に示します。

final FadeUpAnimation anim = new FadeUpAnimation(v);
anim.setInterpolator(new AccelerateInterpolator());
anim.setDuration(1000);
anim.setFillAfter(true);
new Handler().postDelayed(new Runnable() {
    public void run() {
        v.clearAnimation();
        //Extra work goes here
    }
}, anim.getDuration());
v.startAnimation(anim);

見苦しいかもしれませんが、非常に信頼性が高いと保証できます。私は、他の行へのアニメーションで削除しながら新しい行を挿入しているリストビューに使用します。 AnimationEndを使用したリスナーのストレステストは、信頼性が低いことが判明しました。時々AnimationEndがトリガーされないことがありました。アニメーションが完全に終了しなかった場合に、postDelayed関数の変換を再適用することもできますが、実際に使用しているアニメーションのタイプによって異なります。

57
ShortFuse

投稿の読み方やこの問題の解決策を見つけるのに何日も費やしたことを思い出せずに、移動するオブジェクトが画面領域にない場合(たとえば、画面座標の外にある場合)、OnAnimationEndコールバックが取得されないと呼ばれます。おそらく、アニメーションは開始直後に失敗します(startメソッドが呼び出され、リスナーをコーディングしました)が、logcatには何も書き込まれません。たぶんこれはあなたの場合ではないかもしれませんが、これは最終的に私の問題を解決し、それがあなたにも役立つことを願っています。

9
Lisitso

使用しているview.startAnimation(Animation)AND NOTview.setAnimation(Animation)であることを確認してください。この単純な混乱が問題になる場合があります。

9
ralphgabb

また、アニメーションを使用するときは、setFillAfter()からtrueを忘れないでください。

http://developer.Android.com/reference/Android/view/animation/Animation.html#setFillAfter(boolean)

FillAfterがtrueの場合、このアニメーションが実行した変換は、終了しても持続します。設定されていない場合のデフォルトはfalseです。 AnimationSetを使用してアニメーションをチェーンする場合、これが適用されることに注意してください。 AnimationSet自体が開始される前に、変換は適用されません。

anim.setFillAfter(true);
mToolbar.startAnimation(anim);
3
Entreco

この質問につまずいた人は、代わりにProperty Animationシステムの使用に切り替えることを検討してください http://developer.Android.com/guide/topics/graphics/prop-animation.html

ビューのフェードイン/フェードアウトをアニメーション化する古い方法(AlphaAnimationを使用)にいくつかの問題がありました。 OnAnimationEndは呼び出されませんでした...プロパティアニメーションを使用すると、これらの問題はすべて解決されました。

API <11デバイスをサポートする場合、Jake Whartonの https://github.com/JakeWharton/NineOldAndroids が道です

2
MrMaffen

OnAnimation startとinAmimationEndでも問題なく動作するコードを試しました。

TranslateAnimation anim =new TranslateAnimation(0, 0, -60, 0);
        anim.setDuration(1000);     
        anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation a) {
                    Log.w("Start", "---- animation start listener called"  );
                }
                public void onAnimationRepeat(Animation a) {}
                public void onAnimationEnd(Animation a) {
                    Log.d(" end  ","---- animation end listener called"  );
                }
            });
            mIv.setAnimation(anim);
            mIv.startAnimation(anim);
0
sravan

OverridePendingAnimation(int、int)を使用してみてください。つまり、overridePendingAnimation(0,0)

デフォルトのアニメーションをオーバーライドし、Viewのオブジェクトを使用してメソッドstartAnimationを呼び出すことにより、独自のアニメーションを定義できます。

これが私のサンプルコードです。それがあなたに役立つかどうかわからない。

overridePendingTransition(0,0);
//finish();
v.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fadeout));
startActivity(new Intent(ContentManagerActivity.this,Mainmenu_activity.class));
overridePendingTransition(R.anim.fadein,0);
0
Ravi A

部分的に画面外にあるビューでアニメーションコマンドを開始すると、アニメーションが開始され、onStartListenerが呼び出されますが、アニメーションは完全には実行されません(途中で中断されます)。私の推測では、ビューは画面外であるためキャンセルされ、onFinishは呼び出されません。その回避策として、ハンドラーを開始する独自のアニメーションリスナーを作成し、postDelayedを使用してアニメーション終了イベントをユーザーに通知します。コトリンで:

abstract class PartiallyOffScreenAnimationListener : Animation.AnimationListener, AnimationListener {
    override fun onAnimationRepeat(animation: Animation?) {
        onAnimationRepeat_(animation)
    }
    override fun onAnimationEnd(animation: Animation) {}

    override fun onAnimationStart(animation: Animation) {
        onAnimationStart_(animation)
        Handler().postDelayed({
            onAnimationEnd_(animation)
            animation.setAnimationListener(null)
        }, animation.duration + 50)
    }
}

アニメーションが完全に実行されない場合、ビューが一貫性のない状態のままになる可能性があることに注意してください(たとえば、レイアウトパラメーターをアニメーション化すると、奇妙な中間補間係数がドロップされる可能性があります。そのため、ビューが必要な状態にある終了コールバック。そうでない場合は、手動で設定します。

0
johnny_crq

以下のようにしてください

  1. アニメーションを最終的にする
  2. ハンドラー内で呼び出します
  3. リスナーは一度インスタンス化する必要があります。
  4. クリアなアニメーション。

たとえば、view.clearAnimation();

new Hander().post(
   run() {
final TranslateAnimation ani = new TranslateAnimation(0, 0, 0, 0);
ani.setAnimationListener(mListener);
 }
);

private Animation.AnimationListener mListener = new Animation.AnimationListener() {
}
0
Comshot

待っているアニメーションが終了する前に別のアニメーションを設定していませんか?

コンテキストがないと、それがそのようなものであるかどうかを理解するのが難しくなります...

0
neteinstein

私のようにたくさんのstackoverflowの答えを読んでいるにもかかわらず、まだこの問題を抱えていて解決策を見つけられない人がいる可能性があります!

だから私の場合は:animatorSet

  1. clearAnimationを呼び出すことができる単一のビューはありませんでした。
  2. BackgroundThreadからアニメーションを呼び出していませんでした。

解決策として、animatorSet.end()の直前にanimatorSet.start()を呼び出しました

0
yahya

遅延は、おそらくanim.setDuration(1000)によるものか、スレッドでこれを行っている場合、おそらくコンテキストの切り替えによるものです。遅延時間を操作して、違いに気付くかどうかを確認してください。

0

アニメーションに設定されたDurationを使用し、その中に1000ミリ秒を渡すため、しばらくすると呼び出されます。 0を渡すだけで、呼び出しに時間がかかりません。

0
success_anil