2012-12-26 19 views
7

我有使用Fragment個選項卡式應用程序,以及一個小問題。安卓:setInitialSavedState

MainActivity(延伸FragmentActivity - 沒有代碼保存後,對onCreate佈局規範)包括Fragment稱爲TabsFragment(延伸Fragment,實現OnTabChangeListener)在其佈局(其容納翼片本身在FrameLayout)時,切換出子Fragment s使用Transaction s。

後者子Fragments是實際內容的狀態,當用戶打開設備,訪問另一個應用程序,接聽電話或執行其他操作時,我希望保存其狀態。目前,子Fragment的狀態未保存,但該活動記住正在顯示哪個子Fragment。 (因此,如果我的設備處於橫向模式並在標籤3處於活動狀態時轉動設備,則標籤3將以縱向模式顯示,重置但顯示。因此,某些狀態在未執行任何操作的情況下被保留)。

因爲我有多個佈局(橫向和縱向),清單中的android:configChanges="orientation"不是一個選項 - 我不想使用它,因爲它是一個美化的bandaid。

我正在使用v4支持庫(rev 10),並且在淘汰API後,我碰到了FragmentManager.saveFragmentInstanceState()Fragment.setInitialSavedState(Fragment f)。我已經把saveFragmentInstanceState()對每個子FragmentTabsFragment重寫的onPause()方法。我不知道,如果這個工程,因爲,只要我把setInitialSavedState,它提供了一個IllegalStateException - 但是當我剛剛初始化一個新的子Fragment標籤出現這種情況甚至。它也崩潰時,我把它放入onResumeTabsFragment

代碼片段:

//... this is the 'showTab' method 
if(getFragmentManager().findFragmentByTag(id) == null) 
{ 
    Fragment f = null; 
    if(BASIC_TAB.equals(id)) 
    { 
    f = new BasicTabFragment(); 
    f.setInitialSavedState(basicState); // basicState was set in onPause() 
    getFragmentManager().beginTransaction().replace(tabNo, f, tabID).commit(); 
    } 
} 

如果類似的代碼放置在onResume,我得到以下錯誤:

錯誤片段: FATAL EXCEPTION: main java.lang.RuntimeException: Unable to resume activity (org.example.App/org.example.App/MainActivity): java.lang.IllegalStateException: Fragment already active

-snip-

Caused by: java.lang.IllegalStateException: Fragment already active at android.support.v4.app.Fragment.setIniailSavedState(Fragment.java:507) 
at org.example.App.TabsFragment.onResume(TabsFragment.java:223) 

etc.

Clearly I'm calling setInitialSavedState at the wrong point in the lifecycle, but it's not clear to me when this should happen.

Also I'm beginning to wonder if FragmentManager.saveFragmentInstanceState() is indeed the best thing to use here given the somewhat complex nature of the tabbed setup. If so, what to use? How can I save the state of my application's tabs?

+1

我不認爲你應該setInitialSavedState搞亂。你是否簡單地嘗試覆寫onSaveInstanceState()?這應該是調用允許您保存任何額外的狀態信息。 – jsmith

回答

2

When an Activity is destroyed, the Fragments are detached from the Activity and re-attached when it is recreated. Therefore, the fragments should still exist in their current state. When re-attached, OnCreateView被再次調用。如果你正在初始化所有的東西,就好像它是從頭開始的那樣(即將列表設置爲new ArrayList()),你將會清除片段的狀態。

請嘗試將片段中的實例變量對於需要保存一切(即對於任何文本字段字符串 - 的EditText字段將被自動保存爲你提到)。例如:

 
String text; 
TextView tv; 

public View onCreateView(LayoutInflater i, ViewGroup vg, Bundle b) 
{ 
    // this will re-inflate everything from the layout. If you initialize any text fields here, it will reset them to the value you set in the xml file 
    View v = i.inflate(R.layout.myLayout, vg, false); 

    if(text != null) 
     tv.setText(text); 
} 

當你的TextView價值變動(比如在OnClickListener或類似),除了你用它做什麼,否則設置的text值。片段重新連接後,它會將其設置爲最後一次更改。