android - setRetainInstance(true) + setCustomAnimations(...) = 每个方向变化的动画?

标签 android animation android-fragments

背景

我有一个 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 。

问题

  1. 我该如何解决这个问题?
  2. 为什么添加 fragment 时仍然会出现动画?
  3. 当其他配置发生变化时会发生什么?

解决方法#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/

相关文章:

android - 火力地堡数据库 : Check if node has no children?

android - 闪烁 imageView 几秒钟

ios - 是否可以访问 iOS 系统动画的属性?

javascript - React-Native:上传照片时的进度条动画

java - 为什么 fragment 不在我的抽屉导航中显示布局

java - ListView 中的复选框 onclick() 错误

android如何编写edittext的onclick事件

java - 找不到服务器配置中的 Firebase 不断抛出 OAuth2 客户端 ID

java - 如何改变所有 Activity 的背景偏好变化?

android - Admob Interstitial 关闭现有 Activity