Android高效入門-Fragment片段的由來與生命週期

作者 | 2016-06-02

什麼是Fragment

Fragment片段(或稱為區塊)是Android提供的一個畫面區塊,可將Fragment放在一個Activity中,可使用多個Fragment構成一個手機畫面,所以,Fragment是Activity的子畫面,如下圖:

A4449

在Activity中的每個Fragment擁有自己的生命週期,當Activity進入暫停時,Activity內的Fragment也會自動執行相對的生命週期方法,在Fragment中覆寫這些方法,可自訂區塊的功能設計。例如,何時要重新讀取資料、何時暫停處理資料等。

在2009年Android剛嶄露頭角時,手機的畫面不大,解析度也不高,一個畫面放不了太多資訊,因此使用Activity轉換到另一個Activity的方式來設計功能,如下圖:

A4450

像是在Activity1中顯示消費清單,當按下清單中的其中一個項目時,在Activity2顯示該筆消費的詳細資訊。

但從2010年時平板開始流行後,畫面變大、解析度變高,一個畫面可容納更多的元件了,2011年初Android 3.0推出時,即加入了Fragment元件,可在Activity中加入Fragment區塊,使其可在一個畫面下容納多個區塊的顯示,並自訂每個區塊的內容,或者更換其中一個區塊功能。

手機環境如果仍是Android 3.0(API Level 11)之前的版本,如2.2、2.3等並沒有Fragment類別,如果想要讓使用Fragment類別的應用程式能在這類手機中正常執行,必須要在專案包入額外的支援類別庫,並在程式中使用支援類別庫中的Fragment相關類別,後續文章的實作內容中會詳細說明。

Fragment的生命週期

每個Fragment擁有自己的生命週期,也就是說,在特定的狀況會自動呼叫特定的方法,供使用者依功能需求覆寫這些方法,加入必要的程式碼。依照Fragment產生與出現的順序會執行的方法描述如下:

產生階段(未出現在畫面上)

  1. onAttach方法

當Fragment被加到某個Activity畫面中時,會自動呼叫此方法。

  1. onCreate方法

Fragment被建立時會自動呼叫此方法,可加入初始化元件或資料的程式碼。

  1. onCreateView方法

將在畫面中第一次顯示Fragment時會自動呼叫此方法,必須回傳Fragment畫面的View元件,設計時,請使用方法中的LayoutInflater物件,在此方法中產生畫面元件並回傳。

  1. onActivityCreated方法

當加入本Fragment的Activity被建立時,該Activity的onCreate方法執行完成後,會自動執行此方法。執行完此方法後,Fragment才出現在畫面上。

準備階段(出現在畫面上)

  1. onStart方法

當Fragment出現在畫面中時先執行此方法。

  1. onResume方法

執行完onStart方法後,再自動執行本方法。完成後即在畫面中與使用者互動。

暫停階段

當使用者按下返回鍵,或是程式中將Fragment自某個Activity中移除時,會自動執行以下方法:

  1. onPause方法

進入暫停前第一個執行的方法。

  1. onStop方法

執行完onPause方法後,自動執行本方法。

  1. onDestroyView方法

此時Fragment已不在畫面中,呼叫此方法。

  1. onDestroy方法

當Fragment要被清除之前,會執行此方法。

  1. onDetach方法

與當初被加入的Activity卸載時,會自動執行此方法。

使用Fragment的Activity

Android Studio在建立Activity時雖然可勾選「使用Fragment」,但產生出的類別與版面架構資訊過多,筆者將以較簡潔的方式,在本節建立一個新的測試用專案「FragmentLifeCycle」,由空白活動開始,解說專案架構並實作一些方法以驗證上節所說明的生命週期相關方法。待日後基礎功能清楚後,讀者可自行以較快速的方式產生具Fragment的活動。

1. 建立專案與Activity

專案命名與package資訊如下圖:

A4452

再選擇「Empty Activity」建立空白活動,如下圖:

A4965

2. 建立Fragment類別

一個片段類別必須繼承「Fragment」類別,或是「ListFragment」、「DialogFragment」或「PreferenceFragment」這些子類別。

使用功能表的「New/Fragment/Fragment(Blank) 」可以快速產生一個Fragment,新類別使用預設的名稱「BlankFragment」,並自動產生一個專用的版面配置檔「fragment_blank.xml」,請暫不勾選最下方的選項,如下圖:

A4974

完成後產生一個類別與在res/layout/下的一個版面配置檔,如下圖:

A4977_n

請開啟「res/layout/fragment_blank.xml」,為了未來能辨識這個片段,筆者將其TextView的長與寬都設定成「match_parent」,並更換它的背景顏色,使其看起來如下圖:

A4978

接著請開啟BlankFragment類別,在類別中的onCreateView會自動覆寫,並產生建立View物件的程式碼,預設使用res/layout/fragment_main.xml,如下:

第5行使用方法內的參數inflater物件的inflate方法,依版面配置檔R.layout.fragment_main的設計建立一個View物件,最後回傳該物件。

此時,雖然BlankFragment類別大致完成了,但還未在任何活動中使用,產生BlankFragment物件時,不是呼叫其建構子,而是直接以類別名稱.getInstance()取得物件,例如:

這也是當時建立空白Fragment時勾選「Include fragment factory methods?」所自動產生的類別層級方法。

3. 將Fragment加入到畫面

接下來的工作是將BlankFragment類別加入到MainActivity的版面配置檔,使其能夠顯示在活動畫面中,請打開「res/layout/activity_main.xml」,在左方元件選擇區拉到最下方的Custom分類中點擊「<fragment>」圖示,如下圖:

A4971_n

點擊後自動掃描到本專案有一個BlankFragment類別,請選擇它

A4975_n

再將其放在原本有的TextView的下方,並設定高與寬都為「match_parent」,如下圖:

A4980

加入的fragment元素其預設的ID值為「fragment」,完整的activity_main.xml的原始碼如下:

整個MainActivity與BlankFragment的架構如下圖:

A4981

上圖的MainActivity使用activity_main.xml為版面配置,activity_main.xml中定義了一個BlankFragment類別,該類別中使用了fragment_blank.xml為其版面配置。因此,MainActivity主要顯示BlankFragment的內容,畫面設計主要則是fragment_blank.xml負責,想要自行設計畫面時,可以在fragment_blank.xml中設計畫面元件。

執行結果如下圖:

A4982

實作Fragment生命週期方法

為了觀察Fragment的生命週期,筆者在BlankFragment類別中覆寫上節所提的所有方法,如onAttach、onCreate、onStart、onResume、onActivityCreated、onPause、onStop、onDestroyView、onDestroy、onDetach等方法,並在方法中加入Log語法,在LogCat中顯示除錯訊息,以觀察方法被執行的時機。

整體程式碼如下:

測試與觀察

執行專案後,MainActivity將BlankFragment加入畫面中,並在系統中產生物件時,執行的順序如下圖:

A4983

先執行onAttach,再執行onCreate,接著執行onCreateView取得View物件,再執行onActivityCreated方法後,BlankFragment即顯示在畫面中,之後再連續執行onStart與onResume方法。

接著請按下模擬器的「Home」鍵,讓畫面回到主桌面,此時因為MainActivityFragment區塊被放到系統的背景中,執行的方法順序如下圖:

A4468

與Activity的生命週期相同,先執行onPause,再執行onStop方法後,進入背景。

接著再按下模擬器的最近使用鈕(稱為Recents或Overview鈕)A4470,列出最近使用的應用程式縮圖,再點擊範例應用程式(FragmentLifeCycle),讓它回到前景,執行的方法順序如下圖:

A4472

與Activity的生命週期相同,先執行onStart,再執行onResume方法後,應用程式由背景回到前景。

當應用程式在前景時,按下返回鍵結束Activity時,MainActivityFragment內的方法執行順序如下圖:

A4984

上圖先執行onPause,再執行onStop,應用程式消失在畫面後,再執行onDestroyView、onDestroy,最後執行onDetach方法。

先瞭解Fragment類別後再認識生命週期,對於未來參與專案開發工作時,比較能夠面對不同需求的挑戰,後續文章會將再談不同功能需求的Fragment架構設計。

 

相關文章:

Category: Android Fragment 標籤:, , ,

關於 Hank Tom

專長為程式語言、雲端服務開發,Linux系統管理, 任職:利拓科技 技術長,海林行動科技 技術總監 輔仁大學 兼任助理教授 ,為 Android高效入門>深度學習、CentOS 7建置、管理與伺服器架設實戰、Java網路程式設計、雲端網頁程式設計-Google App Engine應用實作 等書作者

使用Facebook直接回應

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *