2012-06-20 58 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将覆盖您的监听器,并且回调不会触发。