2017-01-19 91 views
1

我的應用程序的主頁有一個FrameLayout。爲什麼片段在使用FrameLayout使用片段事務時調用OnCreate/OnCreateView?

我活動開始時實例化兩個片段,我試圖使用菜單按鈕來切換片段之間。

scanHistoryFrag = new HistoryFragment(); 
scanFrag = new ScanFragment(); 

我從不替換這些對象 - 我在應用程序的整個生命週期中使用相同的對象。然而,當我換他們在我的FrameLayout ...

private void ChangeFragment(Android.Support.V4.App.Fragment fragment) 
{ 
    Android.Support.V4.App.FragmentTransaction ft = SupportFragmentManager.BeginTransaction(); 
    ft.Replace(Resource.Id.fragmentContainer, fragment); 
    ft.Commit(); 
} 

的OnCreate和OnCreateView的呼籲片段再次...這意味着在該片段我做創建後的任何調整都具有初始值再次覆蓋。我似乎無法找到解釋爲什麼會發生這種情況,或者我可能如何避免這種情況。

由OnOptionsItemSelected調用ChangeFragment方法,因爲我使用菜單按鈕來切換它們。

回答

1

我從不替換這些對象 - 我在應用程序的整個生命週期中使用相同的對象。

初始化的Fragment剛剛創建此類對象的實例,這個類的構造函數將被調用,但不會通過Fragment生命週期去除非Fragment添加,以獲取更多信息的子類,你可以參考Fragments。爲了更容易理解它,我個人認爲這個實例保存了這個Fragment類的數據狀態,但生命週期的事件處理這個Fragment的視圖狀態。

這意味着我在該片段上創建的任何調整都會被初始值再次覆蓋。

是的,你說得對。爲了避免與初始值overwritting再次,我們可以緩存片段的視圖OnCreateView例如像這樣:

private View rootView; 

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    // Use this to return your custom view for this Fragment 
    // return inflater.Inflate(Resource.Layout.YourFragment, container, false); 

    if (rootView == null) 
    { 
     //first time creating this fragment view 
     rootView = inflater.Inflate(Resource.Layout.fragmentlayout1, container, false); 

     //Initialization 
     //TODO: 
    } 
    else 
    { 
     //not first time creating this fragment view 
     ViewGroup parent = (ViewGroup)rootView.Parent; 
     if (parent != null) 
     { 
      parent.RemoveView(rootView); 
     } 
    } 
    return rootView; 
} 
+0

你能請詳細說明什麼是else塊發生了什麼?代碼按預期工作,但我不明白爲什麼一個視圖被刪除 – aufty

+0

@aufty,在'OnCreateView'中,我們實際上添加視圖到'ViewGroup'來顯示這個視圖,但「else」塊中的'rootView'是隻有視圖的緩存,在將該緩存添加到ViewGroup之前,我們需要判斷這個緩存是否已經添加到ViewGroup中。如果添加它,我們將其刪除,否則會發生像「此rootView已有父項」這樣的錯誤。 –