2012-06-20 20 views
38

アニメーションの終了後にボタンの表示を設定したいとします。フラグメントトランザクションアニメーションの終了後にアクションを実行する

アニメーションを呼んだ:

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) 

私の断片がなくなっていたときに知っているリスナーをアタッチする方法はありますか?

答えて

13

Fragmentをサブクラス化してonCreateAnimatorをオーバーライドする必要があります。その後、それらのアニメーションをXMLから読み込んでリスナーをアタッチすることができます。

など。彼の答えに道具を@nmw

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; 
    }  
+0

私はこれを試しましたが、 'onCreateAnimation'は決して呼び出されません。私はサポートパッケージv4から 'Fragment'を使用していますが、' onCreateAnimation'だけがなく、 'onCreateAnimation'もありません。違いはありますか? – ffleandro

+0

これまでに気付かなかったのは、アニメーターが3.0以上しかないからです。 http://stackoverflow.com/questions/4817900/android-fragments-and-animationに示すようにフラグメントトランザクションを正しく設定していますか? – nmw

+0

はい、 'FragmentManager fragmentManager = getActivity()。getSupportFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); ft.setCustomAnimations(R.anim.slide_in_right、R.anim.slide_out_left、R.anim.slide_in_left、R.anim.slide_out_right); ft.addToBackStack(null); ft.replace(R.id.tabContainer、fragment); ft.commit(); fragmentManager.executePendingTransactions(); ' – ffleandro

51

アニメーターはAPIレベル11で追加されましたし、Androidのサポートライブラリによって実装されるフラグメントでは動作しません。

がフラグメントアニメーションイベントをリッスンするために、私はサポートライブラリの Fragmentクラスを拡張し、返されたアニメーションオブジェクトにカスタムAnimationListenerを取り付け、 onCreateAnimationをオーバーライド:

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; 
    } 
} 
+8

FragmentManagerImplは独自のリスナを設定するため、falseが入力された場合はリスナーは呼び出されません。 AnimationSetでラップして返すと動作します。 – sergio91pt

+0

@ sergio91ptどのように説明できますか? –

+7

@Sheikh Aman新しいAnimationSetを作成し、アニメーション(リスナーが設定されている)を追加してセットを返します。これにより、FragmentManagerImplは、自分自身をオーバーライドすることなく別のリスナーを設定することができます。 – sergio91pt

6

ここで上記の回答を組み合わせると、私が使用しているサンプルがありますサポートライブラリのフラグメントで正常に終了しました。

単純に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(); 

} 

}

+0

アニメーションを 'AnimationSet'に追加しようとしましたが、終了時にonAnimationコールバックが呼び出されません。 – toobsco42

+0

私のために働いて、AnimationSetを追加するだけです – Santacrab

0

私は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) 
    { 
    } 

注:

  • 親フラグメントは、あなたがそうでない場合はAnimationSetを返す必要がAnimation.IAnimationListener
  • を実装する必要がありますFragmentManagerはリスナーを上書きし、コールバックは起動しません。
関連する問題