アニメーションの終了後にボタンの可視性を設定したい。
それがアニメーションと呼ばれるものです:
Android.support.v4.app.FragmentTransaction fAnimation = this.getActivity().getSupportFragmentManager().beginTransaction();
fAnimation.setCustomAnimations(Android.R.anim.slide_in_left, R.anim.pull_out_to_left);
if (this.isVisible()) {
fAnimation.hide(this);
fAnimation.commit();
}
// code that will be executed when the fragment is gone (after the animation is over)
私のフラグメントがなくなったことを知るためにリスナーをアタッチする方法はありますか?
@nmwが彼の答えで実装するアニメーターは、APIレベル11で追加され、Androidサポートライブラリによって実装されたフラグメントでは動作しません。
フラグメントアニメーションイベントをリッスンするために、サポートライブラリのFragment
クラスを拡張し、onCreateAnimation
をオーバーライドして、返されたAnimationオブジェクトにカスタムAnimationListenerをアタッチしました。
public class MyFragment extends Android.support.v4.app.Fragment {
private static final String TAG = "MyFragment";
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation anim = AnimationUtils.loadAnimation(getActivity(), nextAnim);
anim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.d(TAG, "Animation started.");
// additional functionality
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.d(TAG, "Animation repeating.");
// additional functionality
}
@Override
public void onAnimationEnd(Animation animation) {
Log.d(TAG, "Animation ended.");
// additional functionality
}
});
return anim;
}
}
Fragmentをサブクラス化してonCreateAnimatorをオーバーライドする必要があります。それらのアニメーションをXMLからロードし、リスナーをアタッチできます。
例えば。
public class MyFragment extends Fragment
{
@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim)
{
final int animatorId = (enter) ? R.anim.in_anim : R.anim.out_anim;
final Animator anim = AnimatorInflater.loadAnimator(getActivity(), animatorId);
anim.addListener(new AnimatorListenerAdapter()
{
@Override
public void onAnimationStart(Animator animation)
{
...
}
@Override
public void onAnimationEnd(Animator animation)
{
...
}
});
return anim;
}
上記の回答をここに組み合わせて、サポートライブラリフラグメントで正常に使用しているサンプルを示します。
MenuFragmentを拡張し、リスナーが後で実行するもののコールバックを取得するように設定するだけです。
public class MenuFragment extends Fragment {
private WeakReference<OnMenuClosedListener> onMenuClosedListener;
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation anim = null;
if (enter) {
anim = AnimationUtils.loadAnimation(getActivity(), R.anim.anim_slide_in_top);
} else {
anim = AnimationUtils.loadAnimation(getActivity(), R.anim.anim_menu_slide_out_top);
anim.setAnimationListener(new AnimationListener() {
@Override public void onAnimationStart(Animation animation) {
}
@Override public void onAnimationRepeat(Animation animation) {
}
@Override public void onAnimationEnd(Animation animation) {
onMenuClosed();
}
});
}
// NOTE: the animation must be added to an animation set in order for the listener
// to work on the exit animation
AnimationSet animSet = new AnimationSet(true);
animSet.addAnimation(anim);
return animSet;
}
private void onMenuClosed() {
if (this.onMenuClosedListener != null) {
OnMenuClosedListener listener = this.onMenuClosedListener.get();
if (listener != null) {
listener.onMenuClosed();
}
}
}
public void setOnMenuClosedListener(OnMenuClosedListener listener) {
this.onMenuClosedListener = new WeakReference<MenuFragment.OnMenuClosedListener>(listener);
}
/**
* Callback for when the menu is closed.
*/
public static interface OnMenuClosedListener {
public abstract void onMenuClosed();
}
}
API 26(およびサポートライブラリ)に追加して使用できます
FragmentTransaction runOnCommit (Runnable runnable);
例えば:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_from_left);
ft.show(YourFragment);
ft.commit();
ft.runOnCommit(() -> Your_Action_Here);
Xamarinでこれを行う必要がありました。私の状況では、フラグメントアニメーションが終了したらコールバックが必要でした。ちらつきのない動作を実現する方法を次に示します(これはC#/ Xamarinです):
public override Animation OnCreateAnimation(int transit, bool enter, int nextAnim)
{
Animation anim = base.OnCreateAnimation(transit, enter, nextAnim);
if (anim == null && nextAnim != 0) {
anim = AnimationUtils.LoadAnimation(Activity, nextAnim);
}
anim.SetAnimationListener(this);
return anim;
}
public void OnAnimationEnd(Animation animation)
{
}
public void OnAnimationRepeat(Animation animation)
{
}
public void OnAnimationStart(Animation animation)
{
}
注意:
Animation.IAnimationListener
を実装する必要がありますAnimationSet
を返す必要があります。そうしないと、FragmentManager
がリスナーをオーバーライドし、コールバックが起動しません。