標籤:
一、Fragment的生命週期初探
因為Fragment必須嵌入在Acitivity中使用,所以Fragment的生命週期和它所在的Activity是密切相關的。
如果Activity是暫停狀態,其中所有的Fragment都是暫停狀態;如果Activity是stopped狀態,這個Activity中所有的Fragment都不能被啟動;如果Activity被銷毀,那麼它其中的所有Fragment都會被銷毀。
但是,當Activity在活動狀態,可以獨立控制Fragment的狀態,比如加上或者移除Fragment。
當這樣進行fragment transaction(轉換)的時候,可以把fragment放入Activity的back stack中,這樣使用者就可以進行返回操作。
使用Fragment時,需要繼承Fragment或者Fragment的子類(DialogFragment, ListFragment, PreferenceFragment, WebViewFragment),所以Fragment的代碼看起來和Activity的類似。
每當建立一個Fragment時,首先添加以下三個回調方法:
- onCreate():系統在建立Fragment的時候調用這個方法,這裡應該初始化相關的組件,一些即便是被暫停或者被停止時依然需要保留的東西。
- onCreateView():當第一次繪製Fragment的UI時系統調用這個方法,該方法將返回一個View,如果Fragment不提供 UI也可以返回null。注意,如果繼承自ListFragment,onCreateView()預設的實現會返回一個ListView,所以不用自己 實現。
- onPause():當使用者離開Fragment時第一個調用這個方法,需要提交一些變化,因為使用者很可能不再返回來。
將Fragment載入到Activity當中有兩種方式:
- 方式一:添加Fragment到Activity的布局檔案當中
- 方式二:在Activity的代碼中動態添加Fragment(薦)
第一種方式雖然簡單但靈活性不夠。添加Fragment到Activity的布局檔案當中,就等同於將Fragment及其視圖與activity的視圖綁定在一起,且在activity的生命週期過程中,無法切換fragment視圖。
第二種方式比較複雜,但也是唯一一種可以在運行時控制fragment的方式(載入、移除、替換)。
二、Fragment與Activity的生命週期對比
fragment生命週期樣本
初次載入:(分成兩部分來看)
點擊一下home鍵(或接入電話),列印日誌如下:
重新進入進入程式(或電話結束),列印日誌如下:
點擊back鍵退出程式,列印日誌如下:
通過上面的日誌,我們能夠看出,Fragment和Activity的生命週期太相似了。只是有幾個Activity中沒有的新方法,需要重點介紹一下:
- onAttach方法:Fragment和Activity建立關聯的時候調用(獲得activity的傳遞的值)
- onCreateView方法:為Fragment建立視圖(載入布局)時調用(給當前的fragment繪製UI布局,可以使用線程更新UI)
- onActivityCreated方法:當Activity中的onCreate方法執行完後調用(表示activity執行oncreate方法完成了的時候會調用此方法)
- onDestroyView方法:Fragment中的布局被移除時調用(表示fragment銷毀相關聯的UI布局)
- onDetach方法:Fragment和Activity解除關聯的時候調用(脫離activity)
三、Fragment返回棧的管理
將Fragment添加到返回棧中:
假設現在我們有兩個Fragment:Fragment01和Fragment02,我們現在從Fragment01的介面跳到 Fragment02,然後按Back鍵,發現程式是直接退出了,而不是返回到Fragment01。如果現在想實現以下功能:從Fragment01的 介面跳到Fragment02,然後按Back鍵,會返回到Fragment01。這個功能該怎麼實現呢?這其實就利用到了返回棧的知識。
其實很簡單,FragmentTransaction中提供了一個addToBackStack()方法,可以將一個事務添加到返回棧中。
我們先回顧一下之前動態載入Fragment的代碼,然後在此基礎之上,增加一行代碼就可以將Fragment添加到返回棧中:(即第07行代碼)
//步驟一:添加一個FragmentTransaction的執行個體FragmentTransaction transaction = getFragmentManager().beginTransaction();//步驟二:用add()方法加上Fragment的對象RightFragment rightFragment = new RightFragment();transaction.add(R.id.right, rightFragment);transaction.addToBackStack(null);
//步驟三:調用commit()方法使得FragmentTransaction執行個體的改變生效transaction.commit();
我們在事務提交之前調用了FragmentTransaction的addToBackStack()方法,它可以接受一個名字用於描述返回棧的狀態,一般傳入null即可。
例子
@Override public void onClick(View v) { // TODO Auto-generated method stub transaction = manager.beginTransaction(); 47 switch (v.getId()) { case R.id.button1: Fragment01 fragment01 = new Fragment01(); transaction.replace(R.id.right, fragment01, "fragment01"); transaction.addToBackStack("fragment01");// 添加到Activity管理的回退棧中。 break; case R.id.button2: Fragment02 fragment02 = new Fragment02(); transaction.replace(R.id.right, fragment02, "fragment02"); transaction.addToBackStack("fragment02");// 添加到Activity管理的回退棧中。 break; case R.id.button3: Fragment03 fragment03 = new Fragment03(); transaction.replace(R.id.right, fragment03, "fragment03"); transaction.addToBackStack("fragment03");// 添加到Activity管理的回退棧中。 break; } transaction.commit(); }
運行程式後,介面如下,沒有任何fragment被載入:
點擊按鈕載入fragment01:
點擊按鈕載入fragment02(此時fragment01被替換,並被壓到了棧當中):
註:如果fragment01在替換的時候沒有被壓到棧中,那就會被銷毀,在執行完onDestroyView()方法後,會繼續執行onDestroy()和onDetach()方法。
按Back鍵,fragment01重新返回到螢幕:(fragment02被銷毀)
再按Back鍵,fragment01被銷毀:
註:Fragment的返回棧由Activity管理;而Activity的返回棧由系統管理。
Android_Fragment的生命週期與返回棧BackStack