2012-12-04 42 views
15

後端堆棧是否支持與Android中嵌套片段的交互?嵌套片段和後端堆棧

如果是這樣,我做錯了什麼?在我的實現中,後退按鈕完全忽略了將此事務添加到後端堆棧的事實。我希望這不是因爲嵌套片段的問題,而只是我做了不正確的事情。

下面的代碼是我的片段之一的內部,用於交換與目前任何嵌套的片段呈現出新的片段:

 MyFragment fragment = new MyFragment(); 
    FragmentTransaction ft = getChildFragmentManager().beginTransaction(); 
    ft.setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_left, R.animator.slide_in_from_left, R.animator.slide_out_right); 
    ft.addToBackStack(null); 
    ft.replace(R.id.myFragmentHolder, fragment); 
    ft.commit(); 
+0

任何人看到這個OP可以採取看看另一個,http://stackoverflow.com/questions/13418436/android-4-2-back-stack-behaviour-with-nested-fragments,這解釋更好。 – lcn

回答

28

我有同樣的問題,我想窩片段,併爲每個嵌套片段保留一個後備棧。

但是......似乎這種情況不是由v4支持庫處理的。在庫中的代碼FragmentActivity,我可以找到:

public void onBackPressed() { 
    if (!mFragments.popBackStackImmediate()) { 
     finish(); 
    } 
} 

的mFragments代表活動的FragmentManager,但它似乎沒有這個經理「傳播」的流行,以兒童的經理。 一種解決方法是手動調用popBackStackImmediate()在子管理者,像這樣的活動,從FragmentActivity繼承:

private Fragment myFragmentContainer; 

    @Override 
    public void onBackPressed() { 
      if (!myFragmentContainer.getChildFragmentManager().popBackStackImmediate()) { 
       finish(); //or call the popBackStack on the container if necessary 
      } 
    } 

有可能是一個更好的辦法,更自動化的方式,但對我的需要沒關係,還不錯。

+0

嗯我稍後再給這個鏡頭,並接受它是否有效。 – MikeS

+0

這似乎沒有工作。首先,片段沒有popBackStackImmediate()方法(僅限FragmentManagers)。我嘗試用'this.getFragmentManager()。popBackStackImmediate()'代替,但基本上沒有看到與已經發生的事情不同的東西。 – MikeS

+1

經過你給我的東西,我找到了解決方案!我會編輯你的回答,以包含解決方案,並將其標記爲已接受,因爲你將我的大部分方法都正確答案... – MikeS

-2
@Override 
public void onBackPressed() { 
    FragmentManager fm = getSupportFragmentManager(); 
    if (fm.getBackStackEntryCount() > 0) { 
     fm.popBackStack(); 
     return; 
    } 
    finish(); 
} 
+0

請在答案上添加一些解釋。 – DontVoteMeDown

4

在我目前的項目,我們有多個「嵌套層」,所以我想出了以下的解決方法僅適用於高層管理者片段自動彈出堆棧中:

@Override 
public void onBackPressed() { 
    SparseArray<FragmentManager> managers = new SparseArray<>(); 
    traverseManagers(getSupportFragmentManager(), managers, 0); 
    if (managers.size() > 0) { 
     managers.valueAt(managers.size() - 1).popBackStackImmediate(); 
    } else { 
     super.onBackPressed(); 
    } 
} 

private void traverseManagers(FragmentManager manager, SparseArray<FragmentManager> managers, int intent) { 
    if (manager.getBackStackEntryCount() > 0) { 
     managers.put(intent, manager); 
    } 
    if (manager.getFragments() == null) { 
     return; 
    } 
    for (Fragment fragment : manager.getFragments()) { 
     if (fragment != null) traverseManagers(fragment.getChildFragmentManager(), managers, intent + 1); 
    } 
}