Fragment可有一個view hierarchy,以之與用戶互動。這個view層級能夠根據XML佈局文件被建立(inflated)或經過代碼建立。view層級須要與activity關聯,才能被用戶看見。Fragment的最初的兩個生命週期爲onInflate和onAttach。android
/* 左邊fragment是list,和ListActivity同樣,繼承ListFragment */
public class TitleFragment extends ListFragment{
private FragmentBasicTest myActivity = null;
private int mCurCheckPosition = 0;
…... 略 ……
@Override //【2】在fragment與activity關聯後調用onAttach()。因爲右邊fragment的具體實如今activity的showDetails()中實現,須要獲取activity的對象。 固然也能夠直接用getActivity()獲取。
public void onAttach(Activity activity) {
showInfo("onAttach() is called. activity is " + activity);
showInfo(" getActivity() : " + getActivity());
super.onAttach(activity);
myActivity = (FragmentBasicTest)activity;
}
@Override//【1】首先調用:在Activity調用setContentView()時,xml中有<fragment>時被調用。bundle存貯的是fragment的狀態,並不是初始化的值。通常而言,此時太早,尚未和activity關聯,通常不多須要在此進行處理,除非咱們須要處理fragment的屬性或參數。在API的reference中,Fragment的主要lifecycle甚至沒有將onInflate()列入,所以在實際編程中,會較少用到。
public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
showInfo("onInfalte() is called");
showInfo(" activity : " + activity);
showInfo(" getActivity() : " + getActivity()); //Fragment尚爲關聯activity
showInfo(" attribute是fragment的屬相,例如R.id.titles = " + R.id.titles);
for(int i = 0 ; i< attrs.getAttributeCount() ; i ++){
showInfo(" attribute " + i + " :" + attrs.getAttributeName(i) + " = " + attrs.getAttributeValue(i));
}
showInfo(" bundle : " + savedInstanceState);
super.onInflate(activity, attrs, savedInstanceState);
}
private void showInfo(String s){
Log.d("TitleFragment",s);
}
}編程
咱們看看運行的logcat顯示。咱們能夠看出,在activity調用setContentView時,先調用Flagment中的onflate(),而後調用onAttach()。在onInfalte()中能夠讀取到咱們在xml文件中<fragment… >設置的屬性。在後面實現右邊的fragment中,因爲佈局文件中<fragment …>中並無指定class屬性,而是在代碼中實現,故沒有onInflate()狀態。ide
與activity的關聯:看到onInfalte()和onAttach()均可以得到activity對象,可是若是採用getActivity()來獲取,則發現onInfalte()的階段對處理UI太早,都不能關聯到activity。函數
參數:在整個生命週期,能夠經過getArguments()來獲取參數,可是不能在與activity關聯後進行setArgments(),只能在初始化極早的階段,例如構造函數和onInflate()。佈局
@Override //【3】在建立fragment中進行初始化時調用。注意此處的bundle參數,是存儲fragment的狀態。若是咱們要爲fragment啓動一個後臺線程,能夠考慮將代碼放於此處。
public void onCreate(Bundle savedInstanceState) {
showInfo("onCreate() is called. ");
super.onCreate(savedInstanceState);
}
@Override //【4】建立fragment,並返回fragment的view層次結構,用於對UI的設計。本例繼承了ListFragment實現,由其生成ListView,它的資源ID是android.R.id.list1,或者能夠經過getListView()來獲取。咱們在此不須要在進行特別的處理,僅用於跟蹤生命週期。
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
showInfo("onCreateView() is called. ");
return super.onCreateView(inflater, container, savedInstanceState);
} 學習
onCreate()和onCreateView()都是在activity調用setContentView()時被調用。也就是activity上未完成onCreate(),所以不該該在此加入與activity的view相關的代碼。然後面的生命週期這是在activity完成onCreate()以後調用的。.net
onActivityCreated顧名思義,是在activity完成onCreate()後被調用。咱們能夠在此處理activity的其餘UI操做,而其餘的fragment已經與activity關聯,咱們能夠進行相互間處理。這也是用戶看到UI界面以前的最後一個狀態,對於從saved狀態中從新建立activity及fragment來說是重要狀態。線程
回想一下,在ListActivity中是在setContentView()後面進行Adapter的設置,由於setContentView已經提供了view層級,所以在fragment中具體設置list也放在fragment的onCreateView()以後的生命週期onActivityCreated()中執行。設計
@Override //【5】onActivityCreated()在activity完成onCreate()後執行,在此能夠加入UI設計(onCreateView())以後,UI被用戶看到以前的代碼。
public void onActivityCreated(Bundle savedInstanceState) {
showInfo("onActivityCreated() is called.");
super.onActivityCreated(savedInstanceState);
// 1)經過Adapter進行view和data的關聯
setListAdapter(new ArrayAdapter<String>(getActivity(), //注意:在ListFragment中不要直接和ListView(經過id或者getListView()獲取)關聯,而要用setListAdapter()
android.R.layout.simple_list_item_1,
BooksInfo.TITLES));
ListView lv = getListView();
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lv.setSelection(mCurCheckPosition);
//2)根據書名設置右邊framgent UI。
myActivity.showDetails(mCurCheckPosition);
}3d
這幾個狀態和activty的相應狀體類似,對應爲可視,可互動,不可互動和不可視。和activity的生命週期圖相對比,從不可視的後臺回覆到可視的前臺的過程是onStop()—>onRestart()—>onStart()。而fragment爲onStop()—>onStart()。
當fragment容許與view相關的資源釋放時調用onDestroyView(),清空經過onCreateView()所返回的view。接着,onDestroy()進行最後fragment狀態的清空。最後調用onDetach(),刪除與activity的關聯()。
@Override //當用戶點擊書名,在右邊fragment中顯示相關的內容。在ListFragment中能夠直接經過回調函數onListItemClick來實現。
public void onListItemClick(ListView l, View v, int position, long id) {
mCurCheckPosition = position;
myActivity.showDetails(mCurCheckPosition);
}
本博文涉及的例子代碼,能夠在Pro Android學習:Fragment中下載。