【发布时间】:2015-03-03 12:56:29
【问题描述】:
背景
我有一个带有片段的活动,该片段在创建时需要动画,但在方向改变时不需要。
片段被动态插入到布局中,因为它是导航抽屉式活动的一部分。
问题
我想避免为配置更改重新创建片段,所以我在片段中使用了 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, fragment, 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, fragment, finalFragment .TAG).commit();
}
});
}
我仍然想看看可以做什么,因为这可能会导致您不希望发生的事情(例如,片段的 onDetach)。
解决方法 #2
解决此问题的一种方法是避免通过片段管理器添加动画,而只在片段生命周期内为视图本身执行此操作。 看起来是这样的:
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));
}
【问题讨论】:
-
if I remove the setRetainInstance call, it works,那它是如何工作的呢?你的意思是你需要在每次方向变化时重新创建和重新添加片段(有或没有动画)? -
@user3249477 是的。片段将被重新创建。
-
每次方向改变时,您的活动是否都会被销毁并重新创建?
-
根据@ItaiHanski,请发布您的清单文件
-
你们,清单中没有什么特别之处。它只是一个简单的活动,其中包含一个片段,以我编写的相同方式创建。您更改了方向,并且正在重新创建活动,而片段仍应用于它。
标签: android animation android-fragments