背景
我有一个 fragment 的 Activity ,在创建时需要动画,但在方向改变时不需要。
fragment 被动态插入到布局中,因为它是抽屉导航式 Activity 的一部分。
问题
我想避免为配置更改重新创建 fragment ,所以我在 fragment 中使用了 setRetainInstance。 它有效,但出于某种原因,每次旋转设备时动画也会重新启动。
我做了什么
我已将此添加到 fragment 中:
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
这个 Activity :
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" />
我尝试过的
- 我尝试使用“替换”而不是“添加”来修复它。它没有帮助。
- 我还尝试始终执行 fragment 的替换,如果 fragment 已经存在,则在没有动画的情况下执行替换(在同一 fragment 上)。
- 如果我删除 setRetainInstance 调用,它会起作用,但我想避免重新创建 fragment 。
问题
- 我该如何解决这个问题?
- 为什么添加 fragment 时仍然会出现动画?
- 当其他配置发生变化时会发生什么?
解决方法#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();
}
});
}
我仍然想看看可以做什么,因为这可能会导致您不希望发生的事情发生(例如, fragment 的 onDetach)。
解决方法#2
解决这个问题的一种方法是避免通过 fragmentManager 添加动画,而只在 fragment 生命周期内为 View 本身添加动画。 这是它的样子:
基础 fragment
@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()
方法并在旋转后重新创建 fragment 时阻止动画发生?
如下所示: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);
}
该 fragment 应该是该 Activity 中所有 fragment 都将扩展的基础 fragment 。
关于android - setRetainInstance(true) + setCustomAnimations(...) = 每个方向变化的动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28832397/