
Fragment是Android最常使用的控件之一。一般情況下,我們會在首頁使用到,有的小伙伴也會單Activity和多Fragment的App。我總結(jié)了一下我了解的Fragment知識,希望對看這篇文章的小伙伴有所幫助。
Fragment的概念
Fragment是Android3.0新增的概念,中文意思是“碎片”,它與Activity非常相似,用一個Activity中描述一些行為或者一部分用戶界面,使用多個Fragment可以在一個單獨的Activity中建立多個UI面板,也可以在多個Activity中使用Fragment。
Android運行在各種各樣的設(shè)備中,有小屏幕的手機,超大屏的平板甚至電視。針對屏幕尺寸的差距,很多情況下,都是先針對手機開發(fā)一套App,然后拷貝一份,修改布局以適應(yīng)其他尺寸的。難道無法做到一個App可以同時適應(yīng)手機和平板么,當然了,必須有啊。
Fragment的出現(xiàn)就是為了解決這樣的問題。你可以把Fragment當成Activity的一個界面的一個組成部分,甚至Activity的界面可以完全有不同的Fragment組成,更帥氣的是Fragment擁有自己的生命周期和接收、處理用戶的事件,這樣就不必在Activity寫一堆控件的事件處理的代碼了。更為重要的是,你可以動態(tài)的添加、替換和移除某個Fragment。
Fragment的創(chuàng)建
一個Fragment必須總是被嵌入到一個Activity中,它的生命周期直接被其所屬的宿主Activity生命周期影響,它的狀態(tài)會隨宿主的狀態(tài)變化而變化。
要創(chuàng)建一個Fragment 必須創(chuàng)建一個Fragment的子類,或者繼承自另一個已經(jīng)存在的Fragment的子類.并重寫onCreateView()方法加載UI。
Fragment生命周期
Fragment必須是依存與Activity而存在的,因此Activity的生命周期會直接影響到Fragment的生命周期。下面這張圖很好的說明了兩者生命周期的關(guān)系:

在圖中我們會發(fā)現(xiàn)Fragment比Activity多5個生命周期回到方法:
onAttach(Activity); // 當Activity與Fragment發(fā)生關(guān)聯(lián)時調(diào)用
onCreateView(LayoutInflater,ViewGroup,Bundle); // 創(chuàng)建該Fragment的視圖
onActivityCreate(bundle); // 當Activity的onCreate();方法返回時調(diào)用
onDestoryView(); // 與onCreateView相對應(yīng),當改Fragment被移除時調(diào)用
onDetach(); // 與onAttach()相對應(yīng),當Fragment與Activity的關(guān)聯(lián)被取消時調(diào)用
注意:除了onCreateView,其他所有的方法如果你重寫了,必須調(diào)用父類對于該方法的實現(xiàn)。
Fragment常用的API
Fragment常用的三個類
- android.app.Fragment 主要用于定義Fragment;
- android.app.FragmentManager 主要用于在Activity中操作Fragment;
- android.app.FragmentTransaction 保證一些列Fragment操作的原子性。
獲取FragmentManager的方式
-
getFragmentManager()方法 - v4中FragmentActivity的
getSupportFragmentManager()方法 - 在Fragment中·getChildFragmentManager()`方法
主要操作的都是FragmentTransaction的方法
- 開啟一個事務(wù):
FragmentTransaction transaction = fm.benginTransaction(); - 往Activity中添加一個Fragment:
transaction.add(); - 從Activity中移除一個Fragment,如果被移除的Fragment沒有添加到回退棧,這個Fragment實例將會被銷毀:
transaction.remove(); - 使用另外一個Fragment替代當前的,實際上就是
remove()然后add()的結(jié)合體:transaction.replace(); - 當你的Fragment數(shù)量固定很少時隱藏當前的Fragment,僅僅是設(shè)為不可見的,并不會銷毀。多的時候,可能會出現(xiàn)OOM異常:
transaction.hide(); - 顯示之前隱藏的Fragment:
transaction.show(); - 會將view從UI中移除,和remove()不同,此時的Fragmengt的狀態(tài)依然由FragmentManager維護:
detach(); - 創(chuàng)建View視圖,附加到UI上并顯示:
attach(); - 提交一個事務(wù):
transaction.commit();
Activity中添加Fragment
方法一(Activity的布局文件中加入標簽)
在XML中配置更加簡單一點,但是靈活性不夠,不能在同一個位置去切換多個不同的Fragment
<fragement
android:id="@+id/myfragment"
android:name="包名.Fragment類名"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
注意:fragment必須設(shè)置id或者tag,并且要指定name類名
方法二(使用FragmentTransaction的add()方法加入fragment)
1.獲取到FragmentManager,在Activity中可以直接通過getFragmentManager得到。
FragmentManager fragmentManager = getFragmentManager();
2.開啟一個事務(wù),通過調(diào)用beginTransaction方法開啟。
FragmentTransaction fragmentTransaction =fragmentManager.beginTransaction();
3.向容器內(nèi)加入Fragment,一般使用add或者replace方法實現(xiàn),需要傳入容器的id和Fragment的實例。
fragmentTransaction.replace(Activity設(shè)置的布局中的ViewGroup組件id, 需要替換的Fragment實例);
fragmentTransaction.replace(Activity設(shè)置的布局中的ViewGroup組件id, 需要替換的Fragment實例);
// 也可以使用三參的方法,傳遞一個Tag
4.提交事務(wù),調(diào)用commit方法提交。
fragmentTransaction.commit();
Fragment回退棧
類似與Android系統(tǒng)為Activity維護一個任務(wù)棧,我們也可以通過Activity維護一個回退棧來保護每次Fragment事務(wù)發(fā)生的變化。如果你將Fragment任務(wù)添加到回退棧,當用戶點擊后退按鍵時,將看到上次保存的Fragment。一旦Fragment完全從回退棧中彈出,用戶再次點擊后退鍵,則退出當前Activity。
示例
假設(shè)現(xiàn)在我們有兩個Fragment:Fragment1和Fragment2,我們現(xiàn)在從Fragment1的界面跳到Fragment2,然后按Back鍵,發(fā)現(xiàn)程序是直接退出了,而不是返回到Fragment1。
如果現(xiàn)在想實現(xiàn)以下功能:從Fragment1的界面跳到Fragment2,然后按Back鍵,會返回到Fragment1,就需要加入回退棧了,F(xiàn)ragmentTransaction中提供了一個addToBackStack()方法,可以將一個事務(wù)添加到返回棧中。
1. transaction.add(R.id.right, rightFragment);
2. transaction.addToBackStack(null);
我們在事務(wù)提交之前調(diào)用了FragmentTransaction的addToBackStack()方法,它可以接受一個名字用于描述返回棧的狀態(tài),一般傳入null就可以了。
Fragment與Activity通信
因為所有的Fragment都是依附于Activity的,所以通信起來并不復(fù)雜,大概歸納為:
- 如果你Activity中包含自己管理的Fragment的引用,可以通過引用直接訪問所有的Fragment的public方法。
- 如果Activity中未保存任何Fragment的引用,那么沒關(guān)系,每個Fragment都有一個唯一的TAG或者ID,可以通過getFragmentManager.findFragmentByTag()或者findFragmentById()獲得任何Fragment實例,然后進行操作。
- 在Fragment中可以通過getActivity得到當前綁定的Activity的實例,然后進行操作。
需要注意的是:如果在Fragment中需要Context,可以通過調(diào)用getActivity(),如果該Context需要在Activity被銷毀后還存在,則使用getActivity().getApplicationContext()。
Fragment與Fragment通信
Fragment可以通過獲取Activity的引用拿到FragmentManager,在去獲取對方的引用。
DialogFragment
DialogFragment在Android 3.0時被引入。是一種特殊的Fragment,用于在Activity的內(nèi)容之上展示一個模態(tài)的對話框。典型的用于:展示警告框,輸入框,確認框等等。
DialogFragment的好處和用法
使用DialogFragment來管理對話框,當旋轉(zhuǎn)屏幕和按下后退鍵時可以更好的管理其聲明周期,它和Fragment有著基本一致的聲明周期。且DialogFragment也允許開發(fā)者把Dialog作為內(nèi)嵌的組件進行重用,類似Fragment(可以在大屏幕和小屏幕顯示出不同的效果)。
使用DialogFragment至少需要實現(xiàn)onCreateView或者onCreateDIalog方法。
onCreateView即使用定義的xml布局文件展示Dialog。onCreateDialog即利用AlertDialog或者Dialog創(chuàng)建出Dialog。