2016-08-22 15 views
1

如果在XML佈局文件中聲明瞭一些Fragment,則預計看起來像SetRetainInstance不理解setRetainInstance(或Xamarin Android中的RetainInstance)如何工作?

但是如果Fragment被動態加載到主ActivityOnCreate回調中的某個容器中,該怎麼辦?在這種情況下,我看不出setRetainInstance的含義。

看看這個代碼:

protected override void OnCreate(Bundle bundle) { 
    base.OnCreate(bundle); 
    var f = new SomeFragment(); 
    var ft = FragmentManager.BeginTransaction(); 
    ft.Replace(Android.Resource.Id.Content, f); 
    ft.Commit(); 
} 

你可以看到,每次的OnCreate被調用(當屏幕旋轉時,如),創建一個新的SomeFragment和充滿活動的主要內容。

現在,即使我宣佈保持基準,以片段的實例變量(場),並創建它,只有當它爲空,這樣的事情:

SomeFragment f; 
protected override void OnCreate(Bundle bundle) { 
    base.OnCreate(bundle); 
    if(f == null) { 
     f = new SomeFragment(this); 
     f.RetainInstance = true; 
    } 
    var ft = FragmentManager.BeginTransaction(); 
    ft.Replace(Android.Resource.Id.Content, f); 
    ft.Commit(); 
} 

這也不起作用,每次活動是創建時,字段f最初仍爲空(未保留)。我發現在這裏工作的唯一解決辦法是宣佈領域f爲靜態的,就像這樣:

static SomeFragment f; 

有了,我甚至不需要(在Java或setRetainInstance)使用RetainInstance。事實上,動態加載Fragments的要求非常流行,因此RetainInstance似乎不太有用?

或者我錯過了一些簡單的東西,仍然利用RetainInstance?問題是使用RetainInstance並動態加載碎片,如果你有一些解決方案或模式在這裏使用,請與我分享,謝謝!

回答

3

雖然我對Xamarin不熟悉,但我可以用Java回答這個問題。

而不是使用

replace(int containerViewId, Fragment fragment) 

的你應該使用

replace(int containerViewId, Fragment fragment, String tag) 

例如,

FragmentManager fragmentManager = getFragmentManager(); 
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
ExampleFragment fragment; 
fragment = (ExampleFragment) fragmentManager.findFragmentByTag("tag"); 
if(fragment == null) 
    fragment = new ExampleFragment(); 
fragmentTransaction.replace(R.id.fragment_container, fragment, "tag"); 
fragmentTransaction.commit(); 

但是,如果你是在後臺運行壽命長的任務,你應該只使用setRetainInstance。你可以看看this blog post。更多地提醒重新創建片段,因爲它可以避免意外的行爲(例如,不初始化某些變量)。

+0

yes看起來像是有效的,所以你的解決方案我們也不需要使用'setRetainInstance'(儘管目的似乎是相似的)。感謝您關於何時實際使用'setRetainInstance'的建議。對於我的用例,我只需要管理所有打開的碎片並在它們之間切換,而無需手動維護狀態,並在每次切換片段時重新運行一些代碼。 – Hopeless

+0

好吧,我剛剛嘗試過體驗它,'Fragment'實例可以被發現(某種被保留),但我們仍然需要使用'setRetainInstance'來防止重新創建Fragment(使用默認值無參數構造函數)。構造函數肯定會被調用,但不知怎麼它仍然通過使用FragmentManager的標籤找到,View的狀態(如某些EditText的文本)仍然保留,但數據成員(在Fragment類中定義)不會保留。 – Hopeless

相關問題