Android Fragment 深度解析

有過一些面試經(jīng)驗的人基本都深有體會商虐,每次面試一般都會問到Fragment的知識,所以,今天我就單獨把Fragment拿出來與大家分享一下.

會涉及到Fragment如何產(chǎn)生秘车,什么是Fragment典勇,F(xiàn)ragment生命周期,如何靜態(tài)和動態(tài)使用Fragment叮趴,F(xiàn)ragment回退棧割笙,F(xiàn)ragment事務(wù),以及Fragment的一些特殊用途眯亦,例如:沒有布局的Fragment有何用處伤溉?Fragment如何與Activiy交互?Fragment如何創(chuàng)建對話框搔驼?Fragment如何與ActionBar集成等等...

1谈火、Fragment的產(chǎn)生與介紹

Android運行在各種各樣的設(shè)備中,有小屏幕的手機舌涨,超大屏的平板甚至電視糯耍。針對屏幕尺寸的差距,很多情況下囊嘉,都是先針對手機開發(fā)一套app温技,然后拷貝一份,修改布局以適應(yīng)什么超級大屏的扭粱。難道無法做到一個app可以同時適應(yīng)手機和平板嗎舵鳞?答案是,當(dāng)然有琢蛤,那就是Fragment.Fragment出現(xiàn)的初衷就是為了解決這樣的問題蜓堕。

你可以把Fragment當(dāng)成Activity一個界面的一部分,甚至Activity的界面由完全不同的Fragment組成博其,更帥氣的是Fragment有自己的聲明周期和接收套才、處理用戶的事件,這樣就不必要在一個Activity里面寫一堆事件慕淡、控件的代碼了背伴。更為重要的是,你可以動態(tài)的添加峰髓、替換傻寂、移除某個Fragment。

2携兵、Fragment的生命周期

Fragment必須是依存于Activity而存在的疾掰,因此Activity的生命周期會直接影響到Fragment的生命周期。官網(wǎng)這張圖很好的說明了倆者的關(guān)系:可以看到Fragment比Activity多了幾個額外的生命周期回調(diào)函數(shù):

onAttach(Activity);//當(dāng)Activity與Fragment發(fā)生關(guān)聯(lián)時調(diào)用

onCreateView(LayoutInflater,ViewGroup,Bundle);//創(chuàng)建該Fragment的視圖

onActivityCreate(bundle);//當(dāng)Activity的onCreate()徐紧;方法返回時調(diào)用

onDestoryView();//與onCreateView相對應(yīng)个绍,當(dāng)改Fragment被移除時調(diào)用

onDetach();//與onAttach()相對應(yīng)勒葱,當(dāng)Fragment與Activity的關(guān)聯(lián)被取消時調(diào)用

注意:除了onCreateView,其他的所有方法如果你重寫了巴柿,必須調(diào)用父類對于該方法的實現(xiàn)。

3死遭、靜態(tài)的使用Fragment

接下來广恢,就是實踐的時候了,要注意了呀潭,開始寫代碼嘍~~~~

這是使用Fragment最簡單的一種方式钉迷,把Fragment當(dāng)成普通的控件,直接寫在Activity的布局文件中钠署,用布局文件調(diào)用Fragment糠聪。

步驟:

1、繼承Fragment谐鼎,重寫onCreateView決定Fragment布局舰蟆。

2、在Activity中聲明此Fragment,就當(dāng)和普通的View一樣狸棍。

下面展示一個例子(我使用倆個Fragment作為Activity的布局身害,一個Fragment用于標(biāo)題布局,一個Fragment用于內(nèi)容布局)草戈。

TitleFragment的布局文件塌鸯,在這里我們可以看出,我們可以每個Fragment當(dāng)中進行單獨的布局:


TitleFragment.java文件唐片,在這里我們能夠看到丙猬,可以在各個Fragment當(dāng)中進行獨立的初始化空間并且處理按鈕之類的事件,減輕了Activity的負(fù)擔(dān)费韭,我們在Activity中就沒有必要寫一大推初始化控件和事件響應(yīng)的代碼了茧球,這樣就使我們的代碼看上去更加的簡潔了,可讀性大大提高了揽思。

publicclassTitleFragmentextendsFragment {privateImageButton mButton;

@SuppressLint("NewApi")

@OverridepublicView onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

View view= inflater.inflate(R.layout.title_fragment, container,false);

mButton=(ImageButton)view.findViewById(R.id.id_title_left_btn);

mButton.setOnClickListener(newOnClickListener() {

@OverridepublicvoidonClick(View v) {

Toast.makeText(getActivity(),"i am an ImageButton in TitleFragment ! ",

Toast.LENGTH_SHORT).show();

}

});returnview;

}

}


同理還有ContentFragment的布局文件content_fragment.xml


同理還有ContentFragment.java文件


publicclassContentFragmentextendsFragment {

@OverridepublicView onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {returninflater.inflate(R.layout.content_fragment, container,false);

}

}

下面就是主Activity以及他的布局文件

MainActivity.java文件


publicclassMainActivityextendsActivity {

@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.activity_main);

}

}

activity_main.xml文件袜腥,在這里我們可以看到,我們把Fragment就當(dāng)做普通的控件一樣钉汗,在xml文件中使用羹令。


運行效果截圖如下:

注:由于時間原因,就沒有上傳源碼损痰,如果需要demo源碼的話福侈,可以留言,我單獨發(fā)你一下...

4卢未、動態(tài)的使用Fragment

上面已經(jīng)演示了最簡單的使用Fragment的方式肪凛,下面分享一下如何動態(tài)的添加堰汉、更新、以及刪除Fragment伟墙。

首先是翘鸭,MainActivity的布局文件activity_main.xml,該文件布局文件上面的頂部是一個TitleFragment戳葵,是一個靜態(tài)聲明的Fragment就乓。

中間也是一個Fragment,但是這個Fragment是動態(tài)使用的拱烁。

最下面是四個按鈕生蚁。用include標(biāo)簽包含外部的布局文件進來的。



然后是戏自,MainActivity.java文件邦投。也是我們這個demo當(dāng)中最重要的代碼文件,首先是將上面的布局文件通過setContentView()加載進來.然后是通過setDefaultFragment()擅笔;將默認(rèn)的ContentFragment動態(tài)的加載進來志衣。接下來就是通過我們在最下面防止的四個按鈕可以隨意的動態(tài)切換Fragment。這也是為什么Fragment會有如此火的原因吧~~~^^




從上面的代碼剂娄,我們可以看出蠢涝,我們可以使用FragmentManager對Fragment進行動態(tài)的加載,這里使用的replace方法~~~下一節(jié)我們會詳細(xì)的介紹FragmentManager的常用API阅懦。和二。。耳胎。^^

注:如果使用android3.0一下的版本惯吕,需要引入v4的包,然后Activity繼承FragmentActivity怕午,然后通過getSupportFragmentManager()獲得FragmentManager對象,不過還是建議把Menifest文件的uses-sdk的minSdkVersion和targetSdkVersion都改為11以上废登,這樣就不必引入v4的包了。

代碼的中間有倆個動態(tài)加載進來的Fragment郁惜,這個和靜態(tài)使用ragment的聲明方式是一樣的堡距,寫一個繼承Fragment的類,然后設(shè)置相應(yīng)的布局兆蕉,由于時間的關(guān)系羽戒,我這里只寫了倆個Fragment,現(xiàn)在把這倆個的代碼頁貼出來:

第一個Fragment和他相應(yīng)的布局文件:




好了虎韵,現(xiàn)在基本的代碼都有了易稠,我們把demo的運行圖貼出來給大家分享一下(注:時間原因,沒注意布局以及圖片的美化包蓝,只是功能的實現(xiàn))驶社,這是分別點擊下面第一個和第二個按鈕的效果圖企量,從而實現(xiàn)了中間用一個Fragment動態(tài)的加載這倆個Fragment的顯示。


ps:為了代碼的簡潔亡电,就不添加按鈕的點擊變化什么的了届巩,主要講解功能了~~~

5、Fragment常用的API:

Fragment常用的三個類:

android.app.Fragment 主要用于定義Fragment

android.app.FragmentManager 主要用于在Activity中操作Fragment

android.app.FragmentTransaction 保證一些列Fragment操作的原子性逊抡,熟悉事務(wù)這個詞姆泻,一定能明白~

a、獲取FragmentManage的方式:

getFragmentManager() // v4中冒嫡,getSupportFragmentManager

b、主要的操作都是FragmentTransaction的方法

FragmentTransaction transaction = fm.benginTransatcion();//開啟一個事務(wù)

transaction.add()

往Activity中添加一個Fragment

transaction.remove()

從Activity中移除一個Fragment四苇,如果被移除的Fragment沒有添加到回退棧(回退棧后面會詳細(xì)說)孝凌,這個Fragment實例將會被銷毀。

transaction.replace()

使用另一個Fragment替換當(dāng)前的月腋,實際上就是remove()然后add()的合體~

transaction.hide()

隱藏當(dāng)前的Fragment蟀架,僅僅是設(shè)為不可見,并不會銷毀

transaction.show()

顯示之前隱藏的Fragment

detach()

將此Fragment從Activity中分離榆骚,會銷毀其布局片拍,但不會銷毀該實例

attach()

將從Activity中分離的Fragment,重新關(guān)聯(lián)到該Activity妓肢,重新創(chuàng)建其視圖層次

transatcion.commit()//提交一個事務(wù)

注意:常用Fragment的哥們捌省,可能會經(jīng)常遇到這樣Activity狀態(tài)不一致:State loss這樣的錯誤。主要是因為:commit方法一定要在Activity.onSaveInstance()之前調(diào)用碉钠。

上述纲缓,基本是操作Fragment的所有的方式了,在一個事務(wù)開啟到提交可以進行多個的添加喊废、移除祝高、替換等操作。

值得注意的是:如果你喜歡使用Fragment污筷,一定要清楚這些方法工闺,哪個會銷毀視圖,哪個會銷毀實例瓣蛀,哪個僅僅只是隱藏陆蟆,這樣才能更好的使用它們。

a揪惦、比如:我在FragmentA中的EditText填了一些數(shù)據(jù)遍搞,當(dāng)切換到FragmentB時,如果希望會到A還能看到數(shù)據(jù)器腋,則適合你的就是hide和show溪猿;也就是說钩杰,希望保留用戶操作的面板,你可以使用hide和show诊县,當(dāng)然了不要使勁在那new實例讲弄,進行下非null判斷。

b依痊、再比如:我不希望保留用戶操作避除,你可以使用remove(),然后add()胸嘁;或者使用replace()這個和remove,add是相同的效果瓶摆。

c、remove和detach有一點細(xì)微的區(qū)別性宏,在不考慮回退棧的情況下群井,remove會銷毀整個Fragment實例,而detach則只是銷毀其視圖結(jié)構(gòu)毫胜,實例并不會被銷毀书斜。那么二者怎么取舍使用呢?如果你的當(dāng)前Activity一直存在酵使,那么在不希望保留用戶操作的時候荐吉,你可以優(yōu)先使用detach。

上述已經(jīng)介紹完成了Fragment常用的一些方法口渔,相信看完样屠,大家一定清楚了Fragment的產(chǎn)生理由,以及如何使用Fragment搓劫,再根據(jù)API的講解瞧哟,也能明白,曾經(jīng)為何覺得Fragment會出現(xiàn)一些列亂七八槽的問題枪向,終究是因為沒有弄清楚其生命周期勤揩。

由于篇幅原因,剩下的內(nèi)容留到下一篇了秘蛔。在下一篇陨亡,會介紹:

1、如何管理Fragment回退棧

2深员、Fragment如何與Activity交互

3负蠕、Fragment與Activity交互的最佳實踐

4、沒有視圖的Fragment的用處

5倦畅、使用Fragment創(chuàng)建對話框

6遮糖、如何與ActionBar,MenuItem集成等~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叠赐,一起剝皮案震驚了整個濱河市欲账,隨后出現(xiàn)的幾起案子屡江,更是在濱河造成了極大的恐慌,老刑警劉巖赛不,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惩嘉,死亡現(xiàn)場離奇詭異,居然都是意外死亡踢故,警方通過查閱死者的電腦和手機文黎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來殿较,“玉大人耸峭,你說我怎么就攤上這事×芨伲” “怎么了抓艳?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長帚戳。 經(jīng)常有香客問我,道長儡首,這世上最難降的妖魔是什么片任? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮蔬胯,結(jié)果婚禮上对供,老公的妹妹穿的比我還像新娘。我一直安慰自己氛濒,他們只是感情好产场,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著舞竿,像睡著了一般京景。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骗奖,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天确徙,我揣著相機與錄音,去河邊找鬼执桌。 笑死鄙皇,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仰挣。 我是一名探鬼主播伴逸,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膘壶!你這毒婦竟也來了错蝴?” 一聲冷哼從身側(cè)響起洲愤,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漱竖,沒想到半個月后禽篱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡馍惹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年躺率,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片万矾。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡悼吱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出良狈,到底是詐尸還是另有隱情后添,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布薪丁,位于F島的核電站遇西,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏严嗜。R本人自食惡果不足惜粱檀,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望漫玄。 院中可真熱鬧茄蚯,春花似錦、人聲如沸睦优。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汗盘。三九已至皱碘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間衡未,已是汗流浹背尸执。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缓醋,地道東北人如失。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像送粱,于是被迫代替她去往敵國和親褪贵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Fragment概述 Fragment是Activity中用戶界面的一個行為或者說是一部分。主要是支持大屏幕上動態(tài)...
    wangling90閱讀 11,524評論 5 76
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,737評論 25 707
  • 想不到的事情脆丁,我們其實根本就沒有想過世舰,做不到的事情,其實我們根本就沒有做過槽卫,而愛不到的人跟压,或許也真的并未愛過 天亮...
    有讀閱讀 205評論 0 0
  • 有些人相識只是一瞬,也許再也不見歼培。但震蒋,沒有誰會永遠(yuǎn)的停留在誰的生命中,不是嗎躲庄? 再也不會那么容易被打動查剖,過了那個迷...
    差不多的差不多閱讀 254評論 0 0
  • 在讀書排行榜、公眾號文章噪窘、朋友圈笋庄、音樂評論等都能看到這本書的身影,無不是頗高的贊譽與其深遠(yuǎn)的影響倔监。買了一本南海...
    半倚秋兮閱讀 238評論 0 0