原做者爲: 蒼山。感謝他分享的內容,如今分享出來給eoeAndroid的各位同胞。 詳情參考http://www.eoeandroid.com/thread-71642-1-1.html和http://blog.csdn.net/w553000664/article/details/7869258 概述 Fragment 表現 Activity 中用UI的一個行爲或者一部分.能夠組合多個fragment放在一個單獨的activity中來建立一個多界面區域的UI,並能夠在多個activity裏重用某一個fragment.把fragment想象成一個activity的模塊化區域, 有它本身的生命週期, 接收屬於它的輸入事件,而且能夠在activity運行期間添加和刪除. Fragment 必須老是被嵌入到一個activity中, 它們的生命週期直接被其所屬的宿主activity的生命週期影響.例如, 當activity被暫停,那麼在其中的全部fragment也被暫停; 當activity被銷燬,全部隸屬於它的fragment也被銷燬. 然而,當一個activity正在運行時(處於resumed狀態),咱們能夠獨立地操做每個fragment, 好比添加或刪除它們. 當處理這樣一個fragment事務時,也能夠將它添加到activity所管理的back stack -- 每個activity中的backstack實體都是一個發生過的fragment事務的記錄. back stack容許用戶經過按下 BACK按鍵從一個fragment事務後退(日後導航). 將一個fragment做爲activity佈局的一部分添加進來時, 它處在activity的viewhierarchy中的ViewGroup中,而且定義有它本身的view佈局.經過在activity的佈局文件中聲明fragment來插入一個fragment到你的activity佈局中,或者能夠寫代碼將它添加到一個已存在的ViewGroup.然而, fragment並不必定必須是activity佈局的一部分;也能夠將一個fragment做爲activity的隱藏的後臺工做者. 本文檔描述瞭如何使用fragment建立你的應用程序, 包括:當被添加到activity的back stack後,fragment如何維護他們的狀態.在activity中,與activity和其餘fragment共享事件.構建到activity的actionbar.以及更多內容. 設計哲學 Android在3.0中引入了fragments的概念,主要目的是用在大屏幕設備上--例如平板電腦上,支持更加動態和靈活的UI設計.平板電腦的屏幕要比手機的大得多,有更多的空間來放更多的UI組件,而且這些組件之間會產生更多的交互.Fragment容許這樣的一種設計,而不須要你親自來管理viewhierarchy的複雜變化. 經過將activity的佈局分散到fragment中, 你能夠在運行時修改activity的外觀,並在由activity管理的back stack中保存那些變化. 例如, 一個新聞應用能夠在屏幕左側使用一個fragment來展現一個文章的列表,而後在屏幕右側使用另外一個fragment來展現一篇文章 – 2個fragment並排顯示在相同的一個activity中,而且每個fragment擁有它本身的一套生命週期回調方法,而且處理它們本身的用戶輸入事件. 所以, 取代使用一個activity來選擇一篇文章,而另外一個activity來閱讀文章 的方式,用戶能夠在相同的activity中選擇一篇文章而且閱讀, 如圖所示: fragment在你的應用中應當是一個模塊化和可重用的組件.即,由於fragment定義了它本身的佈局, 以及經過使用它本身的生命週期回調方法定義了它本身的行爲,你能夠將fragment包含到多個activity中. 這點特別重要, 由於這容許你將你的用戶體驗適配到不一樣的屏幕尺寸.舉個例子,你可能會僅當在屏幕尺寸足夠大時,在一個activity中包含多個fragment,而且,當不屬於這種狀況時,會啓動另外一個單獨的,使用不一樣fragment的activity. 繼續以前那個新聞的例子 -- 當運行在一個特別大的屏幕時(例如平板電腦),app能夠在Activity A中嵌入2個fragment.然而,在一個正常尺寸的屏幕(例如手機)上,沒有足夠的空間同時供2個fragment用, 所以, Activity A會僅包含文章列表的fragment, 而當用戶選擇一篇文章時, 它會啓動Activity B,它包含閱讀文章的fragment. 所以, 應用能夠同時支持圖1中的2種設計模式. 建立Fragment 要建立一個fragment, 必須建立一個 Fragment 的子類 (或者繼承自一個已存在的它的子類). Fragment類的代碼看起來很像 Activity .它包含了和activity相似的回調方法, 例如 onCreate(), onStart(),onPause, 以及 onStop(). 事實上, 若是你準備將一個現成的Android應用轉換到使用fragment,你可能只需簡單的將代碼從你的activity的回調函數分別移動到你的fragment的回調方法. 一般, 應當至少實現以下的生命週期方法:
大多數應用應當爲每個fragment實現至少這3個方法,可是還有一些其餘回調方法你也應當用來去處理fragment生命週期的各類階段.所有的生命週期回調方法將會在後面章節 Handlingthe Fragment Lifecycle 中討論. 除了繼承基類 Fragment , 還有一些子類你可能會繼承:
添加一個用戶界面 fragment一般用來做爲一個activity的用戶界面的一部分,並將它的layout提供給activity.爲了給一個fragment提供一個layout,你必須實現 onCreateView()回調方法, 當到了fragment繪製它本身的layout的時候,Android系統調用它.你的此方法的實現代碼必須返回一個你的fragment的layout的根view. 注意: 若是你的fragment是ListFragment的子類,它的默認實現是返回從onCreateView()返回一個ListView,因此通常狀況下沒必要實現它. 從onCreateView()返回的View, 也能夠從一個xmllayout資源文件中讀取並生成. 爲了幫助你這麼作, onCreateView() 提供了一個LayoutInflater 對象. 舉個例子, 這裏有一個Fragment的子類, 從文件 example_fragment.xml 加載了一個layout:
inflate() 方法有3個參數:
將fragment添加到activity 一般地, fragment爲宿主activity提供UI的一部分, 被做爲activity的整個viewhierarchy的一部分被嵌入. 有2種方法你能夠添加一個fragment到activitylayout: 在activity的layout文件中聲明fragment 你能夠像爲View同樣, 爲fragment指定layout屬性. 例子是一個有2個fragment的activity:
當系統建立這個activity layout時,它實例化每個在layout中指定的fragment,並調用每個上的onCreateView()方法,來獲取每個fragment的layout.系統將從fragment返回的 View直接插入到<fragment>元素所在的地方. 注意: 每個fragment都須要一個惟一的標識,若是activity重啓,系統能夠用來恢復fragment(而且你也能夠用來捕獲fragment來處理事務,例如移除它.) 有3種方法來爲一個fragment提供一個標識:
撰寫代碼將fragment添加到一個已存在的ViewGroup. 當activity運行的任什麼時候候, 均可以將fragment添加到activitylayout.只需簡單的指定一個須要放置fragment的ViewGroup.爲了在你的activity中操做fragment事務(例如添加,移除,或代替一個fragment),必須使用來自FragmentTransaction 的API. 能夠按以下方法,從你的Activity取得一個 FragmentTransaction 的實例:
添加一個無UI的fragment 以前的例子展現了對UI的支持, 如何將一個fragment添加到activity. 然而,也可使用fragment來爲activity提供後臺行爲而不用展示額外的UI. 要添加一個無UI的fragment, 須要從activity使用 add(Fragment, String) 來添加fragment (爲fragment提供一個惟一的字符串"tag", 而不是一個view ID).這麼作添加了fragment,但由於它沒有關聯到一個activity layout中的一個view, 因此不會接收到onCreateView()調用.所以沒必要實現此方法. 爲fragment提供一個字符串tag並非專門針對無UI的fragment的 –也能夠提供字符串tag給有UI的fragment – 可是若是fragment沒有UI,那麼這個tag是僅有的標識它的途徑.若是隨後你想從activity獲取這個fragment, 須要使用 findFragmentByTag(). 管理Fragment 要在activity中管理fragment,須要使用FragmentManager. 經過調用activity的getFragmentManager()取得它的實例. 能夠經過FragmentManager作一些事情, 包括:
處理Fragment事務 關於在activity中使用fragment的很強的一個特性是:根據用戶的交互狀況,對fragment進行添加,移除,替換,以及執行其餘動做.提交給activity的每一套變化被稱爲一個事務,可使用在 FragmentTransaction 中的 API 處理.咱們也能夠保存每個事務到一個activity管理的backstack,容許用戶經由fragment的變化往回導航(相似於經過activity日後導航). 從 FragmentManager 得到一個FragmentTransaction的實例 :
在調用commit()以前, 你可能想調用 addToBackStack(),將事務添加到一個fragment事務的backstack. 這個back stack由activity管理, 並容許用戶經過按下 BACK按鍵返回到前一個fragment狀態. 舉個例子, 這裏是如何將一個fragment替換爲另外一個, 並在後臺堆棧中保留以前的狀態:
若是添加多個變化到事務(例如add()或remove())並調用addToBackStack(),而後在你調用commit()以前的全部應用的變化會被做爲一個單個事務添加到後臺堆棧, BACK按鍵會將它們一塊兒回退. 添加變化到 FragmentTransaction的順序不重要, 除如下例外:
提示: 對於每個fragment事務, 你能夠應用一個事務動畫,經過在提交事務以前調用setTransition()實現. 調用 commit() 並不當即執行事務.偏偏相反, 它將事務安排排期, 一旦準備好,就在activity的UI線程上運行(主線程).若是有必要, 不管如何, 你能夠從你的UI線程調用executePendingTransactions()來當即執行由commit()提交的事務. 但這麼作一般沒必要要,除非事務是其餘線程中的job的一個從屬. 警告:你只能在activity保存它的狀態(當用戶離開activity)以前使用commit()提交事務. 若是你試圖在那個點以後提交, 會拋出一個異常.這是由於若是activity須要被恢復,提交以後的狀態可能會丟失.對於你以爲能夠丟失提交的情況, 使用 commitAllowingStateLoss(). 與Activity通訊 儘管Fragment被實現爲一個獨立於Activity的對象,而且能夠在多個activity中使用,但一個給定的fragment實例是直接綁定到包含它的activity的. 特別的,fragment可使用 getActivity() 訪問Activity實例, 而且容易地執行好比在activitylayout中查找一個view的任務.
|