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が呼び出されることを確認しましたが、しばらくしてから呼び出されます(その間に新しいアニメーションを開始しない場合)。
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
関数の変換を再適用することもできますが、実際に使用しているアニメーションのタイプによって異なります。
投稿の読み方やこの問題の解決策を見つけるのに何日も費やしたことを思い出せずに、移動するオブジェクトが画面領域にない場合(たとえば、画面座標の外にある場合)、OnAnimationEndコールバックが取得されないと呼ばれます。おそらく、アニメーションは開始直後に失敗します(startメソッドが呼び出され、リスナーをコーディングしました)が、logcatには何も書き込まれません。たぶんこれはあなたの場合ではないかもしれませんが、これは最終的に私の問題を解決し、それがあなたにも役立つことを願っています。
使用しているview.startAnimation(Animation)
AND NOTview.setAnimation(Animation)
であることを確認してください。この単純な混乱が問題になる場合があります。
また、アニメーションを使用するときは、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);
この質問につまずいた人は、代わりにProperty Animationシステムの使用に切り替えることを検討してください http://developer.Android.com/guide/topics/graphics/prop-animation.html
ビューのフェードイン/フェードアウトをアニメーション化する古い方法(AlphaAnimationを使用)にいくつかの問題がありました。 OnAnimationEndは呼び出されませんでした...プロパティアニメーションを使用すると、これらの問題はすべて解決されました。
API <11デバイスをサポートする場合、Jake Whartonの https://github.com/JakeWharton/NineOldAndroids が道です
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);
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);
部分的に画面外にあるビューでアニメーションコマンドを開始すると、アニメーションが開始され、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)
}
}
アニメーションが完全に実行されない場合、ビューが一貫性のない状態のままになる可能性があることに注意してください(たとえば、レイアウトパラメーターをアニメーション化すると、奇妙な中間補間係数がドロップされる可能性があります。そのため、ビューが必要な状態にある終了コールバック。そうでない場合は、手動で設定します。
以下のようにしてください
たとえば、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() {
}
待っているアニメーションが終了する前に別のアニメーションを設定していませんか?
コンテキストがないと、それがそのようなものであるかどうかを理解するのが難しくなります...
私のようにたくさんのstackoverflowの答えを読んでいるにもかかわらず、まだこの問題を抱えていて解決策を見つけられない人がいる可能性があります!
だから私の場合は:animatorSet
と
解決策として、animatorSet.end()
の直前にanimatorSet.start()
を呼び出しました
遅延は、おそらくanim.setDuration(1000)によるものか、スレッドでこれを行っている場合、おそらくコンテキストの切り替えによるものです。遅延時間を操作して、違いに気付くかどうかを確認してください。
アニメーションに設定されたDurationを使用し、その中に1000ミリ秒を渡すため、しばらくすると呼び出されます。 0を渡すだけで、呼び出しに時間がかかりません。