背景
我有一个活动,片段需要在创建时进行动画处理,但在方向改变时则不需要.
片段被动态插入到布局中,因为它是导航抽屉式活动的一部分.
问题
我想避免为配置更改重新创建片段,所以我在片段中使用了setRetainInstance.
它可以工作,但由于某种原因,每次旋转设备时动画也会重新启动.
我做了什么
我已将此添加到片段中:
@Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); }
这对活动:
final FragmentManager fragmentManager = getSupportFragmentManager(); final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); MyFragment fragment= (MyFragment) fragmentManager.findFragmentByTag(MyFragment.TAG); if (fragment== null) { fragmentTransaction.setCustomAnimations(R.anim.slide_in_from_left,R.anim.slide_out_to_right); fragment= new MyFragment(); fragmentTransaction .add(R.id.fragmentContainer,fragment,MyFragment.TAG).commit(); }
fragment_container.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/fragmentContainer" android:layout_width="match_parent" android:layout_height="match_parent" />
我试过的
>我试图通过使用“替换”而不是“添加”来修复它.它没有帮助.
>我也尝试过总是执行片段的替换,如果片段已经存在,那就不用动画(在同一个片段上).
>如果我删除setRetainInstance调用,它可以工作,但我想避免重新创建片段.
题
>我该如何解决这个问题?
>为什么我仍然可以获得添加片段的动画?
>其他配置发生变化时会发生什么?
解决方法#1
这个解决方案通常有效,但它会给你试图实现的生命周期带来不好的结果:
MyFragment fragment= (MyFragment) fragmentManager.findFragmentByTag(MyFragment.TAG); if (MyFragment== null) { MyFragment= new MyFragment(); fragmentManager.beginTransaction().setCustomAnimations(R.anim.slide_in_from_left,R.anim.slide_out_to_right) .replace(R.id.fragmentContainer,MyFragment.TAG).commit(); } else { //workaround: fragment already exists,so avoid re-animating it by quickly removing and re-adding it: fragmentManager.beginTransaction().remove(fragment).commit(); final Fragment finalFragment = fragment; new Handler().post(new Runnable() { @Override public void run() { fragmentManager.beginTransaction().replace(R.id.fragmentContainer,finalFragment .TAG).commit(); } }); }
我仍然希望看到可以做什么,因为这会导致你不想发生的事情(例如onDetach for the fragment).
解决方法#2
解决此问题的一种方法是避免通过fragmentManager添加动画,并在片段生命周期内为视图本身执行此操作.
这是它的样子:
BaseFragment
@Override public void onViewCreated(final View rootView,final Bundle savedInstanceState) { super.onViewCreated(rootView,savedInstanceState); if (savedInstanceState == null) rootView.startAnimation(AnimationUtils.loadAnimation(getActivity(),R.anim.slide_in_from_left)); } @Override public void onDestroyView() { super.onDestroyView(); if (!getActivity().isChangingConfigurations()) getView().startAnimation(AnimationUtils.loadAnimation(getActivity(),R.anim.fade_out)); }
解决方法
如果在旋转后重新创建片段,您如何覆盖
onCreateAnimation()
方法并阻止动画发生?
如图所示:How to disable/avoid Fragment custom animations after screen rotation
编辑:这是一个示例代码:
BaseFragment.java
... private boolean mNeedToAvoidAnimation; @Override public void onDestroyView() { super.onDestroyView(); mNeedToAvoidAnimation = true; } @Override public Animation onCreateAnimation(int transit,boolean enter,int nextAnim) { // This avoids the transaction animation when the orienatation changes boolean needToAvoidAnimation = mNeedToAvoidAnimation; mNeedToAvoidAnimation = false; return needToAvoidAnimation ? new Animation() { } : super.onCreateAnimation(transit,enter,nextAnim); }
此片段应该是此活动中所有片段将扩展的基础片段.