android3.0以及之後的版本支持fragment技術,低版本要想使用fragment技術需要android.support.v4.app包
獲取fragmentManager的方法不同:
3.0以下:getSupportFragmentManager()
3.0以上:getFragmentManager()
fragment的生命週期與activity的關係如圖:
學習fragment時碰到的幾個名詞:
FragmentActivity:
一個android.support.v4.app中的一個繼承了Activity的類,如果你要在3.0以下使用fragment就需要讓頁面繼承FragmentActivity而不是Activity,FragmentActivity中包含了3.0以下操作fragment的方法,使用方法同3.0以上一樣,只是獲取Manager的方法不同
FragmentPagerAdapter
可以作爲ViewPager的適配器
ListFragment
列表樣式, 自帶一個默認的包含ListView控件的佈局文件,無需手動重寫onCreateView()使用inflat()方法加載自定義佈局文件,只需要重寫onCreate()方法,在其中用setListAdapter()方法綁定適配器,在綁定適配器的時候給item設置一個佈局文件就行了。
若想修改ListView,可以在onCreateView(LayoutInflater, ViewGroup, Bundle)中進行修改,需要注意在自定義的ListFragment對應的佈局文件中,必須指定一個 android:id 爲 “@android:id/list” 的ListView控件!
當然,用戶也可以在ListFragment對應的佈局中包含其它的控件。
顯示:在主activity中使用new關鍵字獲取對象的引用
DialogFragment
Android官方推薦使用DialogFragment創建對話框,可以避免屏幕旋轉導致的問題。
重寫onCreateView()則用定義的xml佈局文件展示Dialog或者重寫onCreateDialog()則需要利用AlertDialog或者Dialog創建出Dialog,在主activity中使用DialogFragment對象的show()方法,顯示對話框。
顯示:在主activity中使用new關鍵字獲取對象的引用
FragmentTabHost
用來代替已廢棄的TabHost,個人感覺和前兩個ListFragment以及DialogFragment有些不同,你可以把FragmentTabHost看作是一個普通控件正常使用,也就是個TabHost使用方法一樣。
需要主頁面的佈局文件中添加控件,然後通過findViewById()來獲取控件,需要注意的是佈局文件中控件使用的標記名稱是<android.support.v4.app.FragmentTabHost>
,id:@android:id/tabhost
(id可以隨便寫)
需要包含三個子標記(經過測試,只用一個id:tabhost(也就是上面那個控件)和一個id:realtabconten也可以(真正的容器FrameLayout):
1、Tab標籤容器TabWidget,id:@android:id/tabs
(id必須是這個)
2、Tab內容容器FrameLayout,id:@android:id/tabcontent
(id必須是這個),注意:這裏屬性中寬高皆爲0dp
3、Tab內容容器FrameLayout,id:@+id/RealTabContent
(id可以隨便寫),注意:這個纔是真正的內容容器
FragmentTabHost可以在佈局文件中定義標籤容器在內容容器的下面,調動RealTabContent的位置到tabhost的上面就行了,此時RealTabContent的屬性最好是:
android:id="@+id/RealTabContent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
相關鏈接:《關於FragmentTabHost中TabWidget不能移到屏幕下面的Bug》
然後,在主activity中使用findViewById()獲取控件後,必須先使用使用控件對象的setup()方法之後才能用addTab()方法來添加標籤,這點和TabHost一樣,不過使用的具體方法有區別,FragmentTabHost應該用:
//setup():
setup(Context context, FragmentManager manager, int containerId)
//參數解釋:
//context:上下文
//manager:使用getSupportFragmentManager()
//containerId:容器id
//×××××××××××××××××××××××××××××××××××××××××
//add()
addTab(TabSpec arg0, Class<?> arg1, Bundle arg2)
//參數解釋:
//arg0:FragmentTabHost對象的newTabSpec()方法獲取,並且需要使用獲取到的TabSpec對象的setIndicator()方法設置標題屬性
//arg1:具體的fragment類(不是new出來的)
//arg2:null即可
詳細的FragmentHostTab與HostTab之間的區別請看:TabHost 和 FragmentTabHost
籠統的Fragment的使用:
只是單純的Fragment,不含:ListFragment,DialogFragment,FragmentTabHost等,不過基本一樣
fragment繼承類和其佈局文件
一個fragment由一個佈局文件和一個繼承了fragment的子類組成,由這個子類處理佈局文件產生的的各種事件
使用時需要讓子類關聯到其佈局文件,關聯方法:
1、重寫fragment類的onCreateView()生命週期方法,
2、然後在onCreateView()中調用方法的傳入參數inflater的inflate()方法並返回獲得的View對象來加載對應的佈局文件
當fragment繼承類和其佈局文件關聯後就可以顯示到頁面上了,顯示方法:
注意:並不是直接把fragment的佈局文件或其中的控件顯示到頁面上
而是在主頁面的佈局文件中使用fragment標記,要注意標記的android:name屬性,由這個屬性的值關聯到fragment繼承類,進而通過fragment繼承類加載到相應的fragment佈局文件
具體顯示到頁面上有兩種方式:
靜態
也就是直接把一個或多個fragment顯示到頁面上,這樣做就相當與把一個fragment看作是一個普通控件(由一個或多個控件組成的控件)來添加到頁面上
只不過這個“控件“(fragment)產生的事件由對應的繼承了fragment的類處理,
而不是像平時那樣在主頁面中爲某個控件findViewById然後添加監聽器,這一步寫在了繼承了fragment的類中
具體步驟:
1、fragment的佈局文件,就像平時的佈局文件一樣
2、繼承了fragment的類,重寫fragment類的onCreateView()生命週期方法,
在onCreateView()中調用方法的傳入參數inflater的inflate()方法並返回獲得的View對象來加載對應的佈局文件
3、主頁面佈局文件中依次寫入需要顯示的fragment標記,通過標記的name屬性關聯到繼承了fragment的類
動態
動態的意思就是可以在不切換activity的前提下,通過某個點擊事件,在同一個區域顯示不同的fragment
要實現這個效果,需要一個FragmentManager管理類和一個FragmentTransaction事務類,還需要一個承載不同fragment的容器,一般是在主頁面中使用一個FrameLayout幀佈局來充當這個容器,
也就是讓一個個fragment在FrameLayout中顯示,但不需要在FrameLayout內寫fragment子標記
如何切換不同的fragment的方法由事務類操作實現
具體步驟:
前兩步與靜態一樣,寫幾個fragment的佈局文件和類並一一對應的關聯起來
3、在主頁面的佈局文件中,需要動態顯示fragment的地方,放一個FrameLayout幀佈局
4、在主頁面的activity類中,通過getFragmentManager()方法獲取到FragmentManager
並通過FragmentManager的beginTransaction()開始並獲取到一個事務FragmentTransaction
5、通過獲取到的FragmentTransaction對象的就可以控制fragment顯示顯示或隱藏到FrameLayout幀佈局
部分控制方法有:
add(),hide(),remove(),replace(),show()等,這些方法都需要fragment對象,也就是要顯示的fragment
通過addToBackStack()方法可以將當前fragment添加到FragmentManager的回退棧,當點擊返回鍵時可以恢復狀態
當操作完成後還必須使用commit()方法提交,提交之後纔會真正生效
總結:
個人表示剛接觸fragment,不容易懂或者說不容易記的地方是fragment的類和對應的佈局文件的關聯,以及如何顯示到頁面大概記憶順序(中間的連接符可以理解爲關聯、對應):
靜態:一個主頁面佈局文件中的<fragment>
標記——一個fragment的繼承類——一個fragment佈局文件
動態:一個主頁面佈局文件中的<FrameLayout>
標記——承載多個fragment的繼承類——各自對應的多個fragment佈局文件雖然理解時的順序是這樣的,但實際寫代碼的時候的順序確實反過來的