? ? ? 【威哥說】自從Google在Android3.0引入Fragment,此后Activity基本成為了Fragment的載體,項目的UI幾乎全部Fragment來實現,本文就來讓你學會Fragment官方的使用方法。
? ? ? 【正文】Android 在 Android 3.0(API 11 級)中引入了Fragment,主要是為了給大屏幕(如平板電腦)上更加動態和靈活的 UI 設計提供支持。由于平板電腦的屏幕比手機屏幕大得多,因此可用于組合和交換 UI 組件的空間更大。利用Fragment實現此類設計時,您無需管理對視圖層次結構的復雜更改。 通過將 Activity 布局分成Fragment,您可以在運行時修改 Activity 的外觀,并在由 Activity 管理的返回棧中保留這些更改。
? ? ? 要想創建Fragment,您必須創建 Fragment 的子類(或已有其子類)。Fragment 類的代碼與 Activity非常相似。它包含與 Activity 類似的回調方法,如 onCreate()、onStart()、onPause() 和onStop()。實際上,如果您要將現有 Android 應用轉換為使用Fragment,可能只需將代碼從 Activity 的回調方法移入Fragment相應的回調方法中。
? ? ? 通常,您至少應實現以下生命周期方法:
? ? ?onCreate()
? ? ? 系統會在創建Fragment時調用此方法。您應該在實現內初始化您想在Fragment暫停或停止后恢復時保留的必需Fragment組件。
? ? ?onCreateView()
? ? ? 系統會在Fragment首次繪制其用戶界面時調用此方法。 要想為您的Fragment繪制 UI,您從此方法中返回的 View 必須是Fragment布局的根視圖。如果Fragment未提供 UI,您可以返回 null。
? ? ? onPause()
? ? ? 系統將此方法作為用戶離開Fragment的第一個信號(但并不總是意味著此Fragment會被銷毀)進行調用。 您通常應該在此方法內確認在當前用戶會話結束后仍然有效的任何更改(因為用戶可能不會返回)。
? ? ? 大多數應用都應該至少為每個Fragment實現這三個方法,但您還應該使用幾種其他回調方法來處理Fragment生命周期的各個階段。
? ? ? 這里介紹幾個Fragment的子類,均是為了方便大家的使用,SDK的封裝:
? ? ? DialogFragment
? ? ? 顯示浮動對話框。使用此類創建對話框可有效地替代使用 Activity 類中的對話框幫助程序方法,因為您可以將Fragment對話框納入由 Activity 管理的Fragment返回棧,從而使用戶能夠返回清除的Fragment。
? ? ? ListFragment
? ? ? 顯示由適配器(如 SimpleCursorAdapter)管理的一系列項目,類似于 ListActivity。它提供了幾種管理列表視圖的方法,如用于處理點擊事件的 onListItemClick() 回調。
? ? ? PreferenceFragment
? ? ? 以列表形式顯示 Preference 對象的層次結構,類似于 PreferenceActivity。這在為您的應用創建“設置” Activity 時很有用處。
? ? ? Fragment通常用作 Activity 用戶界面的一部分,將其自己的布局融入 Activity。
? ? ? 要想為Fragment提供布局,您必須實現 onCreateView() 回調方法,Android 系統會在Fragment需要繪制其布局時調用該方法。您對此方法的實現返回的 View 必須是Fragment布局的根視圖。
? ? ? 注:如果您的Fragment是 ListFragment 的子類,則默認實現會從 ? ? ? ? ? ? onCreateView() 返回一個 ListView,因此您無需實現它。
? ? ? 要想從 onCreateView() 返回布局,您可以通過 XML 中定義的布局資源來擴展布局。為幫助您執行此操作,onCreateView() 提供了一個 LayoutInflater對象。
? ? ? 例如,以下這個 Fragment 子類從 example_fragment.xml 文件加載布局:
public static class ExampleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
? ? ? 在上例中,R.layout.example_fragment 是對應用資源中保存的名為example_fragment.xml 的布局資源的引用。傳遞至 onCreateView() 的 container 參數是您的Fragment布局將插入到的父 ViewGroup(來自 Activity 的布局)。savedInstanceState 參數是在恢復Fragment時,提供上一Fragment實例相關數據的 Bundle。
? ? ? inflate() 方法帶有三個參數:
1.布局的資源 ID;
2.布局父項的 ViewGroup。傳遞 container 對系統向擴展布局的根視圖(由其所屬的父視圖指定)應用布局參數具有重要意義;
3.指示是否應該在擴展期間將擴展布局附加至 ViewGroup(第二個參數)的布爾值。(在本例中,其值為 false,因為系統已經將擴展布局插入container—傳遞 true 值會在最終布局中創建一個多余的視圖組。)
? ? ? 那么如何將該Fragment添加到您的 Activity 中?
? ? ? 通常,Fragment向宿主 Activity 貢獻一部分 UI,作為 Activity 總體視圖層次結構的一部分嵌入到 Activity 中。可以通過兩種方式向 Activity 布局添加Fragment:
? ? ? 在 Activity 的布局文件內聲明Fragment
? ? ? 在本例中,您可以將Fragment當作視圖來為其指定布局屬性。 例如,以下是一個具有兩個Fragment的 Activity 的布局文件:
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
? ? ? fragment標簽中的 android:name 屬性指定要在布局中實例化的 Fragment 類。
? ? ? 當系統創建此 Activity 布局時,會實例化在布局中指定的每個Fragment,并為每個Fragment調用 onCreateView() 方法,以檢索每個Fragment的布局。系統會直接插入Fragment返回的 View 來替代 fragment元素。
? ? ? 注:每個Fragment都需要一個唯一的標識符,重啟 Activity 時,系統可以使用該標識符來恢復Fragment(您也可以使用該標識符來捕獲Fragment以執行某些事務,如將其刪除)。 可以通過三種方式為Fragment提供 ID:
? ? ? 為 android:id 屬性提供唯一 ID
? ? ? 為 android:tag 屬性提供唯一字符串
? ? ? 如果您未給以上兩個屬性提供值,系統會使用容器視圖的 ID
? ? ? 或者通過編程方式將Fragment添加到某個現有 ViewGroup
? ? ? 您可以在 Activity 運行期間隨時將Fragment添加到 Activity 布局中。您只需指定要將Fragment放入哪個 ViewGroup。
? ? ? 要想在您的 Activity 中執行Fragment事務(如添加、刪除或替換Fragment),您必須使用 FragmentTransaction 中的 API。您可以像下面這樣從 Activity 獲取一個 FragmentTransaction 實例:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
? ? ? 然后,您可以使用 add() 方法添加一個Fragment,指定要添加的Fragment以及將其插入哪個視圖。例如:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
? ? ? 傳遞到 add() 的第一個參數是 ViewGroup,即應該放置Fragment的位置,由資源 ID 指定,第二個參數是要添加的Fragment。
? ? ? 一旦您通過 FragmentTransaction 做出了更改,就必須調用 commit() 以使更改生效。這樣我們就把Fragment添加到Activity,運行就可以顯示出來了,趕快試試吧!
本文出自微信公眾號mjw-java,更多內容關注微信公眾號或訪問www.moliying.com