2012-06-20 63 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加載這些動畫並將偵聽器附加到它們上。

E.g.

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',它沒有'onCreateAnimatior',只有'onCreateAnimation'。有什麼區別嗎? – ffleandro

+0

之前沒有注意到,但我想這是因爲動畫師只有3.0+。你是否正確設置了片段事務,如http://stackoverflow.com/questions/4817900/android-fragments-and-animation中所示? – nmw

+0

yes,'FragmentManager fragmentManager = getActivity()。getSupportFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); (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

是@nmw在他的回答實現了動畫製作的API等級11,並將由支持Android庫中實現不會與碎片的工作。

要收聽片段動畫事件,我所提供的支持庫的Fragment類和推翻onCreateAnimation,安裝一個定製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; 
    } 
} 
+8

當輸入爲false時,偵聽器不會被調用,因爲FragmentManagerImpl會設置它自己的偵聽器。返回它用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) 
    { 
    } 

注:

  • 父片段具有實現Animation.IAnimationListener
  • 你必須返回一個AnimationSet否則FragmentManager將覆蓋您的監聽器,並且回調不會觸發。