Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 【Android】11.4 Fragment及其生命周期,androidfragment

【Android】11.4 Fragment及其生命周期,androidfragment

編輯:關於android開發

【Android】11.4 Fragment及其生命周期,androidfragment


分類:C#、Android、VS2015;

創建日期:2016-02-22

一、簡介

Android從3.0開始引入了fragment的概念,主要是為了支持在大屏幕上實現更為動態和靈活的UI設計,比如平板電腦等。由於平板電腦的屏幕要比手機屏幕大許多,這樣就有更多的空間去組合和交換UI組件。

也許這樣比喻你能更快地理解它:和WPF相比,如果將Activity的作用看作類似於WPF的Window或者Page;那麼Fragments的作用就類似於WPF在Window或者Page中包含的一個或多個Frame元素。

本節將分別描述:

  • 如何用fragment來創建Android應用程序,包括將fragment添加到後台棧時如何維護其狀態;
  • 如何在同一個activity中讓多個屬於該activity的fragment共享事件;
  • 如何將多個fragment構建到activity的動作槽(action bar)中;

等等。

二、基本概念

Fragment表現Activity中用戶界面的一個行為或者是一部分行為。你可以在一個單獨的activity上把多個fragment組合成一個多區域的UI,並且可以在多個activity中重復使用。可以將fragment看作是activity的一個模塊組件,它有自己的生命周期,接收它自己的輸入事件,並且可以在activity運行時被添加或者刪除。

1、Fragment必須被嵌入到一個activity中才能使用

Fragment必須被嵌入到一個activity中才能使用,並且fragment的生命周期直接受其宿主activity的生命周期的影響。

例如,一旦某個activity被暫停,它裡面所有的fragment也都被暫停,一旦某個activity被銷毀,它裡面所有的fragment也會被銷毀。但是,當activity正在運行時(處於resumed的生命周期狀態),你可以單獨操控每個fragment,比如添加或者刪除某個fragment。當你執行這樣一項事務時,可以將它添加到一個後台棧中,這個棧由activity管理著——activity裡面的每個後台棧內容實體是fragment發生過的一條事務記錄。這個後台棧允許用戶通過按【Back】鍵(向後導航)回退一項fragment事務。

2、fragment的作用就是將activity的布局分割成若干個部分

將activity的布局分割成若干個fragment後,就可以在運行時控制activity的呈現,並且那些變化會被保存在由activity管理的後台棧中。

例如,新聞應用程序將一個fragment放在左邊顯示文章列表,右邊用另一個fragment來顯示一篇文章,此時兩個fragment都在同一個activity中,並且每個fragment都有其自己的生命周期回調方法序列,用以處理各自的用戶輸入事件。因此,用戶可以在同一個activity中選擇和閱讀文章,而不是在一個activity中選擇文章,卻在另一個activity中去閱讀。

3、可在多個activity中引用同一個fragment

應該將每一個fragment設計為模塊化的和可復用化的activity組件。也就是說,可以在多個activity中引用同一個fragment,這是因為fragment定義了它自己的布局,並且使用它本身生命周期回調的行為。這點尤為重要,原理很簡單,模塊化和復用能讓你改變fragment組合以滿足不同的屏幕尺寸。

設計同時支持平板電腦和手機的應用時,通過不同的布局配置可,就可以復用fragments。例如,在手機上,當同一個activity不能容納更多的fragment時,可能需要通過分離fragments提供一個單區域的界面。

再例如,仍以新聞應用程序為例,當程序運行在平板屏幕設備上時,可以在Activity A中嵌入兩個fragment。但是,當運行在手機屏幕上,就沒有足夠的空間同時容納兩個fragment了,因此Activity A只能引用包含文章列表的fragment,在當用戶選擇其中的一篇文章標題時,就可以啟動Activity B,它包含了用來閱讀文章的第二個fragment。這樣,應用程序通過組合不同的fragments,就可以達到復用的目的,這樣就能同時支持平板電腦和手機。

當將一個fragment作為某個activity布局的一部分時,它就存在於這個activity視圖體系內部的ViewGroup中,並且定義了它自己的視圖布局。可以在activity布局文件中用<fragment>元素把fragment插入到activity的布局中,或者用C#代碼將它添加到一個存在的ViewGroup中。然而,fragment並不是必須顯示在activity布局中,它也可以在activity內隱身工作。

三、基本用法

Fragments有它自己獨立的生命周期,如下圖所示:

1、創建一個Fragment時引發的回調方法

下面介紹創建一個Fragment時引發的回調方法。

(1)Infalate()【常用】

Infalate:充氣式膨脹填充,說白了也就是Fill時寬高都填滿的意思。

當創建一個Fragment時,可以重寫OnCreateView(),通過OnCreateView()返回一個布局,然後再將其填充(inflate)到XML(或AXML)的布局文件中。為了便於你這樣做,OnCreateView()提供了一個LayoutInflater對象。

例如,下面是一個fragment子類,它的布局是從example_fragment.xml載入的:

public static class ExampleFragment : Fragment

{

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

    {

          // 將fragment填充(Inflate)到布局中

          return inflater.inflate(Resources.layout.example_fragment, container, false);

    }

}

傳入OnCreateView()的參數container 是你的frament布局將要被插入的父ViewGroup(來自activity的布局)。如果fragment處於resumed狀態(恢復狀態在操縱fragment生命周期中將作更多討論),參數savedInstanceState是Bundle類的實例,它提供了fragment之前實例的相關數據。

Inflate()方法需要以下3個參數:

  • 要填充(inflate)的布局資源的ID。
  • 被填充的布局的父ViewGroup。傳入container很重要,這是為了讓系統將布局參數應用到被inflate的布局的根view中去,由將要嵌入的父view來指定。
  • 一個布爾值,表明在inflate期間被infalte的布局是否應該附上ViewGroup(第二個參數)。(在這個例子中傳入的是false,因為系統已經將被inflate的布局插入到container容器中——傳入true會在最終的布局裡創建一個多余的ViewGroup)。

創建fragment以後,就可以將這個fragment添加到activity中了。

(2)OnAttach()

當Fragment與Activity關聯之後會調用此方法。這是Fragment准備好後運行的第一個方法。

一般情況下,不要重寫Fragments默認的構造函數,也不要為其實現新的構造函數。這是因為在OnAttach()方法中,Fragments所需的任何組件都可能被重新初始化,這可能會導致在構造函數中所做的工作失效。

(3)OnCreate()【常用】

執行OnAttach()以後,系統會接著調用OnCreate()方法。在重寫此方法的實現代碼中,可以初始化想在fragment中保持的那些必要組件,當fragment處於暫停或者停止狀態之後可重新啟用它們。

當系統調用OnCreate()方法時,宿主Activity的層次視圖可能不會被完全實例化,所以fragment不應再此方法中依賴活動視圖層次結構的任何部分。例如,不要在此方法中執行對UI或應用程序的任何調整。

OnCreate()是Fragment開始收集所需數據的最早時期。此時Fragment運行在UI線程上,所以應該避免任何長時間的處理,如果運行時間確實很長,可考慮在後台線程上執行該處理。

如果調用了SetRetainInstance(true)方法,此方法可能會被跳過。替代方法將在後面詳細描述。

(4)OnCreateView()

OnCreate()完成後系統會調用此方法,用於為fragment繪制用戶界面。該方法需要返回fragment使用的View。如果fragment沒有用戶界面,則返回null。

(5)OnActivityCreated()

當OnCreate()已完成並被Activity托管(或者稱宿主到Activity中)時,系統將調用此方法。這是將fragment調整到用戶界面上顯示之前最後執行的方法。

(6)OnStart()

當恢復包含的Activity時系統將調用此方法,此時該fragment對用戶可見。在許多情況下,該片段將包含它應該執行的代碼,或者在Activity的OnStart()方法中包含它應該執行的代碼。

(7)OnResume()

這是用戶可以與片段交互之前最後調用的方法。比如,在此方法中啟用相機設備、位置服務等功能。不過,由於這些服務會導致電池消耗很快,一般應盡量減少使用這類應用以延長電池的壽命。

2、銷毀一個Fragment時引發的回調方法

下面介紹銷毀一個Fragment時引發的回調方法。

(1)OnPause()【常用】

當調用OnPause()以後,用戶將無法再與該片段進行交互。之所以存在這種情況,是因為一些其他的片段操作修改了此片段,或托管活動(hosting Activity)已暫停。此時,承載此片段的活動很可能仍然可見,比如,獲得焦點的活動是部分透明的或該片段並不占用整個屏幕就是這種情況。

當激活此方法時,它是用戶離開該Fragment的第一個預兆(盡管這並不總意味著fragment被銷毀)。在當前用戶會話結束之前,通常要在這裡提交任何應該持久化的變化(因為用戶可能不再返回)。

(2)OnStop()

該Fragment不再可見。此時托管的活動主機可能已經停止,或者在活動中修改了進行的片段。此回調方法與Activity的OnStop()用途相同。

(3)OnDestroyView()

當與片段關聯的視圖被銷毀時,系統將調用此方法清理與視圖關聯的資源。

(4)OnDestroy()

當不再使用該片段時將調用此方法。此時該片段仍然與活動關聯,但不再具有功能。此方法應該釋放片段正在使用的資源,例如相機使用的SurfaceView等。

如果調用了SetRetainInstance(true)方法,此方法可能會被跳過。替代方法將在後面再詳細描述。

(5)OnDetach()

這是片段不再與活動關聯之前調用的方法。該片段的視圖層次將不存在,此時片段所使用的所有資源都應該在此處被釋放。

(6)使用SetRetainInstance()方法

當重建某個活動時,有時候你可能希望不銷毀指定的某個片段,在這種情況下,可以調用SetRetainInstance()方法來實現這個目的。如果傳遞給此方法的參數為true,當重啟該活動時,系統將使用同一個Fragment實例。如果發生這種情況,在Fragment的生命周期中,將不再調用OnCreate()和OnDestroy(),但是仍會調用其他的回調方法。這一過程在上面的生命周期圖示中用“綠色的虛線”標識了出來。

3、Fragment的狀態管理

在Fragments的生命周期中,可通過Bundle實例保存或恢復Fragment的狀態,由於Bundle實例存儲的僅僅是字符串形式的“鍵/值”對,因此並不需要占用太多的內存。例如:

public override void OnSaveInstanceState(Bundle outState)

{

    base.OnSaveInstanceState(outState);

    outState.PutInt("current_choice", currentCheckPosition);

}

創建Fragment的實例後,即可在重寫的OnActivityCreated()中讀取該實例的狀態。例如:

public override void OnActivityCreated(Bundle savedInstanceState)

{

    base.OnActivityCreated(savedInstanceState);

    if (savedInstanceState != null)

    {

        currentCheckPosition = savedInstanceState.GetInt("current_choice", 0);

    }

}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved