2012-05-17 71 views
13

我正在開發一個基本上有一個ActionBar的應用程序。當我的應用程序啓動時,Activity會創建碎片並將它們附加到每個選項卡,因此當我切換時,我會得到不同的視圖。重新定位變化Android碎片

當我嘗試旋轉設備時出現問題。經過一番掙扎後,我注意到,Android的自動重新創建先前添加的片段是這樣的:

SummaryFragment.onCreate(Bundle) line: 79 
FragmentManagerImpl.moveToState(Fragment, int, int, int) line: 795 
FragmentManagerImpl.moveToState(int, int, int, boolean) line: 1032 
FragmentManagerImpl.moveToState(int, boolean) line: 1014  
FragmentManagerImpl.dispatchCreate() line: 1761 
DashboardActivity(Activity).onCreate(Bundle) line: 864 
... 

,然後我重新碎片像往常一樣。所以我有我想要正確工作的「真實」片段,以及他們的「隱藏」的Android創建的對應物,這些會讓我的應用崩潰。我怎樣才能避免這種行爲?我已經嘗試在SummaryFragment中調用setRetainInstance(false)。

謝謝

回答

35

您需要檢查savedInstanceState [編輯:在您的父活動],如果存在,請不要創建您的片段。

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    if (savedInstanceState == null) { 
     // Do your oncreate stuff because there is no bundle 
    } 
// Do stuff that needs to be done even if there is a saved instance, or do nothing 
} 
+1

不確定這是否與OP相同,但這對我來說是非常有用的。謝謝。 – ssmy

+0

非常感謝@Barak唯一的解決方案,在一週後工作 –

0

如果你有,你可以設置android:configChanges="keyboardHidden|orientation"到活動清單檔案中的兩個方向類似的UI(沒有具體的佈局土地文件)。

如果不提供源代碼,請將片段添加到選項卡,我會盡力幫助您進行改進。

+0

部分用您的答案解決。由於大部分繪圖都是動態完成的,因此我將刪除所有視圖並根據新的方向重新展示它們。 老實說,我不認爲這是一個乾淨的解決方案,但我無法阻止系統瘋狂地爲我創建碎片... – Luke47

+0

這幫助了我,因爲我在更改後一直忘記更新我的佈局文件文件肖像。現在我得到了大約5次。 – buster

+3

將設備插入汽車擴展塢或電視或其他配置更改時會發生令人厭惡的事情:碎片仍會被重新創建。 android:configChanges是邪惡的,除非你真的知道你在做什麼。 – personne3000

0

當您創建活動時,請檢查並確保它不存在。如果存在,則什麼也不做...... Android會爲您重新創建它。

private void initFragment() { 
     FragmentManager fragMgr = getSupportFragmentManager(); 
     if (fragMgr.findFragmentByTag(LEADERBOARD_FRAG_TAG) != null) { return; } 
     frag = new HdrLeaderboardFragment(); 
     FragmentTransaction ft = fragMgr.beginTransaction(); 
     ft.replace(R.id.leaderboard_fragment_wrapper, frag, LEADERBOARD_FRAG_TAG); 
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
     ft.commit(); 
    } 
+1

這樣做還是會增加兩個碎片......我已經擁有的碎片(按照您的建議)加上另一碎片,這實際上讓我發瘋。在定向更改之間重置FragmentManager會很容易...... – Luke47

0

我不確定是否有更好的解決方案,但這是我在最新程序中所做的。

如果系統根據方向更改自動創建片段,並且如果要在主機活動中跟蹤它們,請在主機活動的OnAttachFragment()方法中捕獲它們。他們默認獲得參數,所以你可以使用它們來找出它是哪個片段。

public void onAttachFragment(Fragment fragment) { 
    super.onAttachFragment(fragment); 
    if (fragment != null) { 
     if(fragment.getArguments() != null) { 
      switch (fragment.getArguments().getString(ARG_PARAM1)) { 
       case FragmentATag: 
        if (myFragmentA != fragment) { 
         myFragmentA = (FragmentA) fragment; 
        }      
        break; 
       case FragmentBTag: 
        if (myFragmentB != fragment) { 
         myFragmentB = (FragmentB) fragment; 
        }       
        break;     
      } 
     } 
    } 
    }