【问题标题】:Android fragment backstack animation fail after orientation change方向更改后Android片段回栈动画失败
【发布时间】:2015-05-07 17:10:07
【问题描述】:

我有一个活动,它承载两个片段,一次只显示一个。实际上,用户在不同的环境条件下应该能够在任何给定时间在两者之间切换。

LoginFragment 是用户在登录时看到的第一件事,LockoutFragment 可能会在用户登录后取代 LoginFragment,我们看到他们的帐户被锁定(自然)。

这是典型的情况,但是有一种情况是先显示LockoutFragment,如果说用户正在使用该应用并且他们的帐户由于某种原因被锁定,我们重新打开主机活动( LoginActivity),显示LockoutFragment,但给他们一个“返回登录”按钮,这会切换LoginFragment的外观(也很自然)。

因此,我的目标是允许用户在两​​个片段之间切换,以先显示的为准。我的宿主活动使用以下函数来实现这个效果:

private void showLockoutFragment() {
    if (mLockoutFragment == null) {
        mLockoutFragment = new LockoutFragment();
    }

    transitionToFragment(FRAGMENT_LOCKOUT, mLockoutFragment);
}

private void showLoginFragment() {
    if (mLoginFragment == null) {
        mLoginFragment = new LoginFragment();
    }

    transitionToFragment(FRAGMENT_LOGIN, mLoginFragment);
}

private void transitionToFragment(String transactionTag, Fragment fragment) {
    if (!getFragmentManager().popBackStackImmediate(transactionTag, 0)) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.setCustomAnimations(
                R.animator.fade_in, R.animator.fade_out,
                R.animator.fade_in, R.animator.fade_out);
        ft.addToBackStack(transactionTag);
        ft.replace(R.id.fragment_container, fragment, transactionTag);
        ft.commit();
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // non configuration change launch
    if (savedInstanceState == null) {
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            // decide which fragment to show
            boolean shouldLockout = extras.getBoolean(EXTRA_SHOULD_LOCKOUT);
            if (shouldLockout) {
                showLockoutFragment();
            } else {
                showLoginFragment();
            }
        } else {
            showLoginFragment();
        }
    } else {
        // retrieve any pre-existing fragments
        mLoginFragment = (LoginFragment)getFragmentManager().findFragmentByTag(FRAGMENT_LOGIN);
        mLockoutFragment = (LockoutFragment)getFragmentManager().findFragmentByTag(FRAGMENT_LOCKOUT);
    }
}

这些功能一起工作就像一个魅力,除了一个例外:当应用程序首次启动后,用户

  1. 尝试登录,
  2. 被带到锁定片段,
  3. 重新定位设备,并且
  4. 导航回登录片段,

登录片段现在存在但不可见 - 好像从未播放过 popEnter 动画。我知道它存在,因为我仍然可以与之互动。

还有一点值得注意:

  • 我在两个片段上都有setRetainInstance(true)
  • 在用户从锁定片段重新定向设备时发生
  • 我已经在模拟器和运行 Lollipop 的设备上进行了尝试,结果相同

是否有可能在重新定向后返回堆栈被破坏?

谢谢!

【问题讨论】:

    标签: android animation android-fragments android-orientation fragment-backstack


    【解决方案1】:

    好的,所以问题实际上在于我对setRetainInstance 的使用。根据该方法的文档:

    控制是否在重新创建 Activity 时保留片段实例(例如来自配置更改)。这只能用于不在后台堆栈中的片段。 [强调我的]

    虽然这对我来说似乎相当神秘,但似乎在后台堆栈上的片段上使用 setRetainInstance(true) 可能只会产生意想不到的后果。就我而言,片段似乎被保留了,但它的 popEnter 动画从未被调用(旋转后)。再一次,很奇怪,但我想避免这种组合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 2011-07-16
      • 1970-01-01
      相关资源
      最近更新 更多