Android Fragment生命周期:多屏幕支持
在使用Fragment之前,F(xiàn)ragment的生命周期是一個(gè)需要關(guān)心的問題。目前,要想在Android上開發(fā)出一款A(yù)PP必須得考慮到“碎片化”的問題,或者說必須考慮多屏幕適配,這是每一個(gè)開發(fā)者都必須面對(duì)的問題。
現(xiàn)在市場上手機(jī)的屏幕分辨率、尺寸五花八門,更糟糕的是,除了手機(jī)外還有平板!我們都清楚,就單單屏幕尺寸來說手機(jī)和平板差異很大。所以,當(dāng)我們開 發(fā)應(yīng)用程序的時(shí)候,要謹(jǐn)記我們的APP應(yīng)該能適用于不同的設(shè)備上而且必須達(dá)到***效果,這樣才能確保獲得更佳用戶體驗(yàn)。于是問題就產(chǎn)生了,我們需要調(diào)整應(yīng) 用在手機(jī)和平板上顯示相同的效果,也就是現(xiàn)在所說的多屏幕適配。在之前的一篇帖子里,我已經(jīng)講了怎么用Android的一些特性做多屏幕支持,比如創(chuàng)建不同的布局文件等等。這個(gè)方式現(xiàn)在也還可以這么做,但是已經(jīng)不能滿足我們的要求了。
一個(gè)經(jīng)典的例子是,應(yīng)用中有一個(gè)列表,用戶點(diǎn)擊列表?xiàng)l目就可以顯示詳細(xì)信息。這種情況下,我們可以使應(yīng)用在手機(jī)和平板上有不同的體驗(yàn)效果。在手機(jī)上需要兩個(gè)Activity來完成這個(gè)功能,如圖:
當(dāng)用戶點(diǎn)擊后,出現(xiàn)的界面是這樣的:
而在平板上,我們我們需要好好利用屏幕,把列表和詳情顯示在一起,如圖:
從上面的例子我們清楚地看到,我們需要一個(gè)方法去“合并Activity”,讓其中一個(gè)Activity調(diào)用另一個(gè)時(shí),兩個(gè)Activity都能同時(shí)或者先后顯示。我們需要在不重寫代碼的情況下重新組織界面布局,而僅僅使用多布局來做是不行的,我們需要?jiǎng)e的技術(shù)。
Fragment
在Android3.0上引入了一個(gè)新概念叫Fragment。它有自己的布局文件,可以作為組件排布,也可以 相互組合去實(shí)現(xiàn)不同的布局顯示。使用Fragment可以重復(fù)利用代碼,并且可以滿足不同設(shè)備尺寸的需求。Fragment不能單獨(dú)存在,只能存在于 Activity中,而一個(gè)Activity可以擁有多個(gè)Fragment。很重要的一點(diǎn)是,F(xiàn)ragment可以和Activity中的其它組件一起使 用,無需重寫所有Activity的接口。所以使用Fragment就可以這樣來完成上例中“主界面—詳細(xì)界面”的APP需求。
在手機(jī)上是這樣顯示的:
而在平板上是這樣的:
Fragment生命周期
既然我們已經(jīng)知道了Fragment很好用,那么我們也需要知道它的工作原理。Fragment只能存在于(作為容器的)Activity中,每一 個(gè)Fragment都有自己的視圖結(jié)構(gòu),可以像我們之前那樣載入布局。Fragment的生命周期更加復(fù)雜,因?yàn)樗懈嗟臓顟B(tài),如圖:
我們來看一下Fragment完整的生命周期。
- 在Fragment生命周期開始,onInflate方法被調(diào)用。要注意的是,這個(gè)方法只在我們直接用標(biāo)簽在布局文件中定義的時(shí)候才會(huì)被調(diào)用。我們可以在這個(gè)方法中保存一些在xml布局文件中定義的配置參數(shù)和一些屬性。
- 這一步過后就輪到onAttach被調(diào)用了。這個(gè)方法在Fragment綁定到它的父Activity中的時(shí)候被調(diào)用,我們可以在這里保存它和Activity之間的引用。
- 之后onCreate會(huì)被調(diào)用。這是最重要的步驟之一。Fragment就是在這一步中產(chǎn)生的,可以用這個(gè)方法來啟動(dòng)其它線程來檢索數(shù)據(jù),比如從遠(yuǎn)程服務(wù)器中啟動(dòng)。
- onCreateView這個(gè)方法是在Fragment創(chuàng)建自己的視圖結(jié)構(gòu)的時(shí)候被調(diào)用,在這個(gè)方法中我們會(huì)載入Fragment的布局文件,就像我們在ListView控件中載入布局一樣。在這個(gè)過程中,我們不能保證父Activity是否已經(jīng)創(chuàng)建,所以有一些操作我們不能在這里完成。
- 可以看到,在onActivityCreated后Activity才算是建立完成。到這一步,我們的Activity就創(chuàng)建成功并激活了。我們可以隨時(shí)使用它了。
- 下一步就是onStart了,在這里我們做的事和Activity中的onStart一樣,在這個(gè)方法中Fragment雖然可以顯示,但是還不能和用戶進(jìn)行交互,只有在onResume后Fragment才能開始和用戶進(jìn)行交互操作。在這個(gè)過程后,F(xiàn)ragment就已經(jīng)啟動(dòng)并運(yùn)行起來了。
- 也許會(huì)暫停Activity。Activity的OnPause方法會(huì)被調(diào)用。這時(shí)候Fragment的onPause方法也會(huì)被調(diào)用。
- 系統(tǒng)也可能會(huì)銷毀Fragment的視圖顯示,發(fā)生這種情況時(shí)onDestroyView方法就被調(diào)用了。
- 之后,如果系統(tǒng)需要完全銷毀整個(gè)Fragment的話,onDestroy方法就會(huì)被調(diào)用了。這時(shí)候我們就需要釋放掉所有可用的連接了,因?yàn)檫@個(gè)時(shí)候Fragment馬上就要被殺掉了。雖然是在準(zhǔn)備銷毀的過程中,但是Fragment仍然綁定在父Activity中。
- ***一步就是把Fragment從Activity中解綁,即調(diào)用onDetach方法。
怎么創(chuàng)建一個(gè)Fragment
現(xiàn)在我們了解了Fragment的生命周期了,接著我們就需要知道怎么創(chuàng)建一個(gè)Fragment并綁定到Activity中,***件要做的事就是繼承android.app.Fragment來寫一個(gè)Fragment,假設(shè)我們的Fragment叫做Fragment1,創(chuàng)建和定義如下:
- public class Fragment1 extends Fragment {
- ...
- }
就像我們上面說的,F(xiàn)ragment只能存在于Activity中,所以我們必須要在某處定義它,有兩種方式:
- 直接在xml布局文件中定義;
- 在xml布局文件中定義一個(gè)占位符,然后動(dòng)態(tài)地在Activity中操作Fragment;
我們定義Fragment的方式會(huì)影響它的生命周期,因?yàn)樵谏鲜?**種情況下onInflate方法會(huì)被調(diào)用,而第二種情況下它的生命周期是從onAttach方法開始的。
如果我們在XML文件中定義Fragment的話,我們需要:
- <fragment android:id="@+id/f1"
- class="com.survivingwithandroid.fragment.Fragment1"
- android:layout_width="match_parent"
- android:layout_height="20dp"/>
然而如果我們在XML中用占位符的話,需要再做一些工作。
布局框架和Fragment
如果我們在XML布局文件中定義Fragment的話,就不能自由、動(dòng)態(tài)修改Fragment了,還有別的方法可以讓我們可以更靈活地操作:使用時(shí)需要在XML文件中定義:
- <FrameLayout android:id="@+id/fl1"
- android:layout_width="match_parent"
- android:layout_height="200dp"/>
在Activity里面還需要做一點(diǎn)工作,因?yàn)槲覀儽仨毷謩?dòng)初始化Fragment,然后把它“插入”到FrameLayout中。
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Fragment2 f2 = new Fragment2();
- FragmentTransaction ft = getFragmentManager().beginTransaction();
- ft.replace(R.id.fl1, f2);
- ft.commit();
- }
關(guān)于FragmentTransaction等內(nèi)容的討論我們留到下一篇文章再說吧,本文就到這里了。
【移動(dòng)開發(fā)視頻課程推薦】
- iOS培訓(xùn)之Objective-C基礎(chǔ)視頻教程(40集)
- Cocos2d-x從零開始【5天掌握跨平臺(tái)游戲開發(fā)利器】(12集)
- Objective C編程基礎(chǔ)(24集)
- Android技術(shù)輕松入門課程(12集)
- 微信開放平臺(tái)-Android應(yīng)用接入(4集)
- Cocos2d-x跨平臺(tái)游戲開發(fā)入門基礎(chǔ)(29集)
- iOS開發(fā)視頻教程-iOS網(wǎng)絡(luò)編程【高級(jí)篇】(39集)
- 移動(dòng)應(yīng)用用戶體驗(yàn)設(shè)計(jì)高級(jí)課程(60集)
- 從零學(xué)習(xí)iOS開發(fā)–UI多視圖(30集)
- iOS開發(fā)視頻教程【基礎(chǔ)入門篇】