2016-12-29 13 views
1

我使用支持庫開發了帶碎片的應用程序。我只使用一個活動。 佈局由具有摺疊工具欄佈局和導航視圖的協調器佈局組成。 在選擇導航項目我執行的NavigationItemSelectedListener如下:onResume調用「死」片段 - 如何正確恢復?

switch (item.getItemId()) { 
       default: 
        return false; 
       case R.id.mainmenu_start: 
        navi.clear(); 
        navi.navigate(new StartFragment(), R.id.fragment_container); 
        return true; 
       // ... More menu entries 
      } 

所以在選擇新項目時,我清除返回堆棧(navi.clear()),並更換一個新的顯示片段。

我遇到的問題是:「舊」(替代)碎片不會被刪除/拆卸

所以,當我瀏覽到StartFragment,然後導航到另一個片段,然後再次選擇StartFragment中,onResume被調用兩次:
一旦上了「老」 /第一StartFragment,一旦新創建的一個。

我該如何避免這種行爲?我想要重複使用現有片段(第一個)創建一個新的 - 但使用這兩個導致大量問題...

爲了調查此行爲,我給每個片段一個唯一的(增量)ID:When導航到新的片段,onResume在幾個較舊的碎片上被調用,但不是全部。
例如:我總是選擇相同的菜單條目進行導航。這是 「事件」 發生的歷史,其中,所述數字表示片段ID(所有片段是相同的類(StartFragment)):

  1. 創建1,簡歷1
  2. 創建2,簡歷1,簡歷2
  3. 創建3,簡歷1,簡歷3
  4. 創建4,簡歷2,簡歷3,恢復4

所以有時 「舊」 的片段缺失,稍後再回來。 onResume有時也被稱爲完全不同的片段。 (所以,當我打開片段2較早,上的onResume片段2創建一個新片段1時,也被稱爲...)

爲了完整
的導航功能:

public void clear() { 
    FragmentManager fragmentManager = ((MainActivity)context).getSupportFragmentManager(); 
    fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
} 



public void navigate(Fragment fragment, int container, HashMap<String, Pair<String, View>> sharedElements) { 
    this.hideKeyboard(); 
    FragmentTransaction ft = ((MainActivity)context).getSupportFragmentManager().beginTransaction(); 
    ft.replace(container, fragment); 
    ft.addToBackStack(null); 
    ft.commit(); 
    ((MainActivity)context).getDrawerLayout().closeDrawers(); 
} 
+1

首先想到這種特殊情況下可以實現:你試過popBackStackImmediate代替popBackStack?有什麼區別? –

+1

謝謝:)這似乎是正確的解決方案!也許你想發佈這個答案,所以我可以接受它 – Kryptur

+0

當然,我會重新發布它作爲一個單獨的答案 –

回答

1

發帖爲回答以備將來參考。

我認爲你的問題是popBackStack()沒有立即生效,但計劃運行在下一個事件循環傳遞,在你的情況是太遲了,併產生不良影響。應該幫助的是強制片段管理器事務完成。

它可以通過調用executePendingTransactions()或在popBackStackImmediate()