Android Fragment生命週期——多螢幕支援

chris發表於2014-04-03

在使用Fragment之前,Fragment的生命週期是一個需要關心的問題。目前,要想在Android上開發出一款APP必須得考慮到“碎片化”的問題,或者說必須考慮多螢幕適配,這是每一個開發者都必須面對的問題。

現在市場上手機的螢幕解析度、尺寸五花八門,更糟糕的是,除了手機外還有平板!我們都清楚,就單單螢幕尺寸來說手機和平板差異很大。所以,當我們開發應用程式的時候,要謹記我們的APP應該能適用於不同的裝置上而且必須達到最優效果,這樣才能確保獲得更佳使用者體驗。於是問題就產生了,我們需要調整應用在手機和平板上顯示相同的效果,也就是現在所說的多螢幕適配。在之前的一篇帖子裡,我已經講了怎麼用Android的一些特性做多螢幕支援,比如建立不同的佈局檔案等等。這個方式現在也還可以這麼做,但是已經不能滿足我們的要求了。

一個經典的例子是,應用中有一個列表,使用者點選列表條目就可以顯示詳細資訊。這種情況下,我們可以使應用在手機和平板上有不同的體驗效果。在手機上需要兩個Activity來完成這個功能,如圖:

Android_fragment_list3

當使用者點選後,出現的介面是這樣的:

Android_fragment_details4

而在平板上,我們我們需要好好利用螢幕,把列表和詳情顯示在一起,如圖:

Android_fragment-tablet3

從上面的例子我們清楚地看到,我們需要一個方法去“合併Activity”,讓其中一個Activity呼叫另一個時,兩個Activity都能同時或者先後顯示。我們需要在不重寫程式碼的情況下重新組織介面佈局,而僅僅使用多佈局來做是不行的,我們需要別的技術。

Fragment

在Android3.0上引入了一個新概念叫Fragment。它有自己的佈局檔案,可以作為元件排布,也可以相互組合去實現不同的佈局顯示。使用Fragment可以重複利用程式碼,並且可以滿足不同裝置尺寸的需求。Fragment不能單獨存在,只能存在於Activity中,而一個Activity可以擁有多個Fragment。很重要的一點是,Fragment可以和Activity中的其它元件一起使用,無需重寫所有Activity的介面。所以使用Fragment就可以這樣來完成上例中“主介面—詳細介面”的APP需求。

在手機上是這樣顯示的:

android_activity_fragment1

而在平板上是這樣的:

android_activity_fragment_tablet1

Fragment生命週期

既然我們已經知道了Fragment很好用,那麼我們也需要知道它的工作原理。Fragment只能存在於(作為容器的)Activity中,每一個Fragment都有自己的檢視結構,可以像我們之前那樣載入佈局。Fragment的生命週期更加複雜,因為它有更多的狀態,如圖:

android_fragment_lifecycle4

我們來看一下Fragment完整的生命週期。

  • 在Fragment生命週期開始,onInflate方法被呼叫。要注意的是,這個方法只在我們直接用標籤在佈局檔案中定義的時候才會被呼叫。我們可以在這個方法中儲存一些在xml佈局檔案中定義的配置引數和一些屬性。
  • 這一步過後就輪到onAttach被呼叫了。這個方法在Fragment繫結到它的父Activity中的時候被呼叫,我們可以在這裡儲存它和Activity之間的引用。
  • 之後onCreate會被呼叫。這是最重要的步驟之一。Fragment就是在這一步中產生的,可以用這個方法來啟動其它執行緒來檢索資料,比如從遠端伺服器中啟動。
  • onCreateView這個方法是在Fragment建立自己的檢視結構的時候被呼叫,在這個方法中我們會載入Fragment的佈局檔案,就像我們在ListView控制元件中載入佈局一樣。在這個過程中,我們不能保證父Activity是否已經建立,所以有一些操作我們不能在這裡完成。
  • 可以看到,在onActivityCreated後Activity才算是建立完成。到這一步,我們的Activity就建立成功並啟用了。我們可以隨時使用它了。
  • 下一步就是onStart了,在這裡我們做的事和Activity中的onStart一樣,在這個方法中Fragment雖然可以顯示,但是還不能和使用者進行互動,只有在onResume後Fragment才能開始和使用者進行互動操作。在這個過程後,Fragment就已經啟動並執行起來了。
  • 也許會暫停Activity。Activity的OnPause方法會被呼叫。這時候Fragment的onPause方法也會被呼叫。
  • 系統也可能會銷燬Fragment的檢視顯示,發生這種情況時onDestroyView方法就被呼叫了。
  • 之後,如果系統需要完全銷燬整個Fragment的話,onDestroy方法就會被呼叫了。這時候我們就需要釋放掉所有可用的連線了,因為這個時候Fragment馬上就要被殺掉了。雖然是在準備銷燬的過程中,但是Fragment仍然繫結在父Activity中。
  • 最後一步就是把Fragment從Activity中解綁,即呼叫onDetach方法。

怎麼建立一個Fragment

現在我們瞭解了Fragment的生命週期了,接著我們就需要知道怎麼建立一個Fragment並繫結到Activity中,第一件要做的事就是繼承android.app.Fragment來寫一個Fragment,假設我們的Fragment叫做Fragment1,建立和定義如下:

就像我們上面說的,Fragment只能存在於Activity中,所以我們必須要在某處定義它,有兩種方式:
– 直接在xml佈局檔案中定義;
– 在xml佈局檔案中定義一個佔位符,然後動態地在Activity中操作Fragment;

我們定義Fragment的方式會影響它的生命週期,因為在上述第一種情況下onInflate方法會被呼叫,而第二種情況下它的生命週期是從onAttach方法開始的。

如果我們在XML檔案中定義Fragment的話,我們需要:

然而如果我們在XML中用佔位符的話,需要再做一些工作。

佈局框架和Fragment

如果我們在XML佈局檔案中定義Fragment的話,就不能自由、動態修改Fragment了,還有別的方法可以讓我們可以更靈活地操作:使用時需要在XML檔案中定義:

在Activity裡面還需要做一點工作,因為我們必須手動初始化Fragment,然後把它“插入”到FrameLayout中。

關於FragmentTransaction等內容的討論我們留到下一篇文章再說吧,本文就到這裡了。

相關文章