轉載請註明出處:http://blog.csdn.net/zhouli_csdn/article/details/45558719
fragment嵌入在activity中使用,它有自己的生命週期,接收它自己的輸入事件。但是它的生命週期受到宿主activity的直接影響,當activity執行pause,fragment也會,destroy時也一樣。在acitivity運行時,你可以動態的添加或者刪除fragment,同時你可以把它添加進管理它的activity的返回棧中(activity的每一個返回棧節點都是一個發生的fragment記錄),返回棧允許用戶通過返回鍵返回。
activity存活於activity的viewgroup中,你可以在activity的layout文件中聲明一個fragment或者在代碼中動態的向一個已知的viewgroup中添加。然而,fragment不是必須成爲activity的一部分layout,你可以使用一個沒有UI的invisible的fragment作爲activity的工作者。
本文會講訴如何在activity中使用fragment,fragment在添加進返回棧中是如何保存狀態的,和activity以及其它fragment分享一些events,對actionBar一些幫助等等。
設計理念(Design Philosophy)
創建一個fragment
如果你希望使用fragment,你可以簡單的將activity中回調方法的代碼移到對應的fragment中。你需要實現至少以下方法:
oncreate:當創建fragment的時候,系統會調用此方法。你可以在這裏初始化一些基本的組件(那些你想在fragment暫停或者停止之後又resume)
onCreateView:當fragment第一次繪製自己的Ui的時候,系統會調用此方法。你可以返回一個將作爲fragment根layout的view或者返回null.
onPause:通常在這裏你應該提交一些改變,保存在用戶當前回話中。
fragment的一些子類:
DialogFragment:顯示一個浮動對話框。比使用dialog好,因爲允許添加到堆棧可以返回到之前的fragment。
ListFragment:通過adapter管理一些子條目相當於listview。onCreateView方法默認返回一個listview,不必實現此方法。
PreferenceFragment:類似於PreferenceActivity,用來爲應用創建一個settings。
通過inflater.inflate(R.layout.example_fragment, container, false);返回一個view給fragment,inflate有三個參數:
1.你想繪製的layout的id
2.是要繪製的layout的parent,系統會將layout parameters給要繪製的view的根。
3.是否將要inflate的layout添加進參數2中。(在這裏爲false,因爲系統已經將它添加進去了,如果爲true,將會創建一個冗餘的viewgroup)。
在activity的layout文件中聲明fragment:
注意:每一個fragment必須包含一個標識,如果activity發生restarted系統用來恢復fragment,並且你可以用來對fragment進行操作(例如刪除)。三種方法添加標識:
1.提供一個id 2.提供android:tag用一個唯一的字符串3.如果前兩者都沒有系統會使用參數2 的id。
在代碼中添加fragment:
使用FragmentTransaction:add,remove,replace操作,之後必須commit使變化生效。
添加一個沒有UI的fragment:
使用add(Fragment,String)方法添加一個fragment(提供一個tag而不是id),因爲沒有和activity的layout中的view關聯,多以不會調用onCreateView方法,可以使用findFragmentBytag方法找到fragment。
管理fragments
使用fetFragmentManager獲得FragmentManager.你可以做以下動作:
1.獲得在activity中的fragment(findFragmentById(提供了UI)或者findFragmentBytag(沒有提供UI)))
2.使用popBackStack從返回棧彈出fragment,類似用戶執行返回鍵
3.註冊一個監聽器addOnBackStackChangeListener,監聽返回棧的變化。
4.其它操作,例如beginFragmentTransaction。
你可以在一個transaction中執行多個add,remove,replace操作,然後添加進返回棧中,然後返回鍵將會一起恢復它們。
當你在執行一個transaction的remove操作的時候,調用了addToBackStack方法,這個fragment被stoped,的用戶返回時它會resume。如果沒有addToBackStack,那麼這個fragment會被銷燬。
調用commit並不會立刻執行transaction,而是在調度UI線程的時候。當然你可以在UI線程調用executePendingtransactions使立即實行。通常你不必做這個,除非這個transaction依賴與其它線程。
警告:你必須在activity保存它的狀態之前commit,如果你在這之後提交會拋出異常。因爲這樣做,提交的狀態會丟失,如果你允許丟失,你可以使用commitAllowingStateLoss。
與activity交互
fragment中可以使用getActivity,activity中可以使用getFragmentManager().findFragmentById(R.id.example_fragment)
一些情況你需要fragment分享一些事件給activity。
例如:Aactivity可以定義一個監聽接口,然後在fragment的onAttach方法中初始化一個監聽對象。例如:
@Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnArticleSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener"); } }
// Container Activity must implement this interface public interface OnArticleSelectedListener { public void onArticleSelected(Uri articleUri); }
將條目添加到操作欄
略:
注意:儘管fragment接收到onItemselected回調方法,activity最先接受到這個方法,如果activity的這個沒有處理它,然後纔會將這個事件傳遞給fragment的回調方法。這同樣適用於Options Menu and context menus.
處理Fragment生命週期
和activity的生命週期一樣
resume:在運行的activity中可見時
paused:另外一個activity在它之上,但是它的宿主仍然有一部分可見
stopped:activity暫停,或者fragment被remove但是被添加進返回棧。activity如果被殺死,fragment也會被殺死。
你可以適用bundle保存fragment的狀態以防activity的進程被殺死。你可以在onSaveInstanceState方法保存fragment的狀態,然後在onCreate或者onCreateView,或者onActivityCreated方法中恢復。
它和activity最重要的區別在於返回棧。activity保存與系統管理的返回棧中,fragment保存在activity管理的返回棧中。
注意:當fragment沒有被綁定到activity(onAttach)或者解除綁定到activity(onDetach),getActivity會返回null.
與activity協調的生命週期
activity每一個生命週期的發生都會導致它的每一個fragment對應的生命週期的發生。它有一個其它的生命週期方法:
onAttach:fragment和activity關聯時調用,activity會被傳遞。
onCreateView:用來返回fragment的view
onActivityCreated:activity的onCreate方法返回時被調用
onDestroyView:當和fragment關聯的view被removed時調用
onDetach:當fragment和activity解除關聯時被調用
fragment的生命週期不會超過activity的生命週期調用。例如:activity調用onCreate,那麼fragment只會調用到onActivityCreated。只有當activity處於onResume狀態時,你可以自由的添加和刪除fragment,這時候fragment的生命週期獨立的改變。
佈局方向:res/layout-land/fragment_layout.xml 橫屏佈局
res/layout/fragment_layout.xml豎屏佈局