在上一篇 學習安卓開發[1] 程式結構、Activity生命周期及頁面通信 中,學習了Activity的一些基礎應用,基於這些知識,可以構建一些簡單的APP了,但這還遠遠不夠,本節會學習如何使用Activity托管Fragment的方式來進行開發 [TOC] 為什麼需要Fragment 單純使用Ac ...
目錄
在上一篇學習安卓開發[1]-程式結構、Activity生命周期及頁面通信中,學習了Activity的一些基礎應用,基於這些知識,可以構建一些簡單的APP了,但這還遠遠不夠,本節會學習如何使用Activity托管Fragment的方式來進行開發
為什麼需要Fragment
單純使用Activity的局限
為什麼需要Fragment呢,這要從Activity的局限說起。在前面使用Activity的過程中已經發現,Activity很容易被銷毀重建,甚至是在設備旋轉的時候也會被銷毀,為了返回之前的狀態需要保存各種界面相關的信息。
再來假設一種比較常見的場景,一個列表界面+明細界面構成的應用,如果用兩個Activity來實現也可以,但如果用戶在平板設備上運行應用,則最好能同時顯示列表和明細記錄,類似網易雲、QQ那樣在屏幕左側約1/3的區域顯示列表,右側剩餘的區域展示詳細信息,這是使用兩個Activity無法滿足的;另外,查看能否在用戶想查看下一條明細時不必回退、再點擊進入明細界面,而是採用在屏幕橫向滑動切換到下一條這樣的快捷手勢呢,這也是兩個Activity無法滿足的。
Fragment介紹
接下來該是Fragment隆重登場的時候了,可以說Fragment就是為了應對UI的靈活需求而生的,Fragment是在API 11中開始引入的,當時Google發佈了第一臺平板設備。
那麼什麼是Fragment呢,Fragment是一種控制器對象,可以在Activity的托管下進行用戶界面的管理,受其管理的界面可以是整個屏幕區域,也可以是一小部分,Fragment(碎片)就是這個意思。
要讓Activity能夠托管Fragment,則需要activity視圖預留fragment插入其中的位置。一個activity視圖中可以插入過個fragment視圖。Fragment本身沒有在屏幕上顯示視圖的能力,所以它必須放置在Activity的視圖層級中。
如何使用Fragment
代碼實現
容器視圖和Activity
在文件activity_fragment.xml中定義容器視圖:
<FrameLayout android:id="@+id/fragment_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" />
在Activity中定義了一個用於放置Fragment的FrameLayout,這個容器視圖可以托管任意的Fragment。
對應Activity的代碼在CrimeActivity.java為:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = new CrimeFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
FragmentManager
這段代碼的作用是:在資源ID為R.id.fragment_container的FrameLayout容器中,找到fragment,然後判斷獲取的fragment是否為空,如果為空則創建新的名為CrimeFragment的Fragment實例,將其添加到FragmentManager所維護的隊列中,併在容器R.id.fragment_container中顯示。
除了這種用代碼將fragment交給Activity托管的方式,還可以在xml中直接將fragment簽入activity,但為了能夠動態地更換fragment,唯一能採用的便是前面採用的代碼的方式。
在設備旋轉或回收記憶體時,Android系統會銷毀Activity,但FragmentManager會將fragment隊列保存下來。Activity被重建時,新的FragmentManager會首先獲取保存的隊列(這就是使用了Fragment後,不會有像之前那樣旋轉就會設備導致狀態丟失的現象的原因)。所以代碼里會先判斷fragment是否為null,只有為null的時候才會重新向隊列中添加fragment。
Fragment的生命周期
Fragment的生命周期如下圖所示:
可見Fragment的生命周期與Activity的生命周期非常類似,實際上Fragment的許多方法對應著activity的生命周期方法。
Fragment的onCreate方法:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
Activity的onCreate方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
兩者的區別在於Fragment.OnCreate()是公共方法,而Activity.OnCreate()是受保護方法,Activity的生命周期方法由操作系統調用,而Fragment的生命周期方法則是由托管它的Activity調用的。