簡體   English   中英

方向更改后,Android片段后堆棧動畫失敗

[英]Android fragment backstack animation fail after orientation change

我有一個活動,其中包含兩個片段,一次僅顯示一個片段。 實際上,通過不同的環境條件,用戶應該能夠在任何給定時間在兩者之間切換。

有一個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)
  • 當用戶從鎖定片段重新定向設備時, 才會發生這種情況
  • 我已經在運行棒棒糖的模擬器和設備上嘗試了相同的結果

重新定向后,后堆棧是否有可能損壞?

謝謝!

好的,事實證明問題出在我對setRetainInstance使用上。 根據該方法的文檔:

控制是否在活動重新創建期間保留片段實例(例如,通過配置更改)。 只能與不在堆棧中的片段一起使用 [強調我的]

雖然這對我來說似乎很神秘,但似乎在后堆棧上的片段上使用setRetainInstance(true)可能會帶來意想不到的后果。 就我而言,該片段似乎保留了下來,但從未調用過其popEnter動畫(旋轉后)。 同樣,很奇怪,但是我想只是避免這種組合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM