一、Fragment簡介
Fragment爲大量不同型號、尺寸、分辨率的設備提供了一種統一的UI優化方案。
Fragment允許將Activity拆分成多個完全獨立封裝的可重用的組件,每個組件有它自己的生命週期。
每個Fragment都是獨立的模塊,並與它綁定的Activity緊密聯繫在一起。多個Activity可以共用一個Fragment。
Fragment展現了良好的適應性和動態構建UI的能力,可以在一個正在顯示的Activity中添加、刪除或替換Fragment。
二、創建Fragment
可以通過集成Fragment類來創建一個Fragment,大多數情況下需要爲Fragment分配一個UI,也可以爲Activity創建一個沒有UI但提供後臺行爲的Fragment。如果Fragment需要UI,可以重新OnCreateView
方法來填充並返回所需要的View。
代碼示例:
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 創建或者填充Fragment的UI,並且返回它。
// 如果這個Fragment沒有UI則返回null
return inflater.inflate(R.layout.my_fragment, container, false);
}
}
三、FragmentManager介紹
每個Activity都包含一個FragmentManager來管理它所包含的Fragment。可以通過使用getFragmentManager
方法來訪問FragmentManager:
FragMentManager fragmentManager = getFragMentManager();
FragmentManager提供了很多方法來訪問當前添加到Activity上的Fragment、通過執行FragmentManager來添加、刪除和替換Fragment。
四、向Activity中添加Fragment
想要把一個Fragment添加到一個Activity鍾,最簡單的方法是在Activity佈局中使用fragment標籤來包含它,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<fragment
android:name="包名.Fragment類名"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/my_fragment"/>
</LinearLayout>
一旦一個Fragment被填充後,它就成爲一個ViewGroup,會在Activity內顯示和管理它所包含的UI。
如果想要在運行時通過添加、刪除或者替換Fragment的方式修改UI,更好的方法是在佈局文件中添加ViewGroup作爲Fragment的容器,然後在代碼中使用FragmentTransaction來創建相應的Fragment並添加到ViewGroup中。
五、使用FragmentTransaction
在程序運行時,FragmentTransaction可以用來在一個Activity內添加、刪除或替換Fragment。它同樣也支持顯示過渡動畫的規範以及是否在back棧中包含Transaction。
一個新的FragmentTransaction是通過使用Activity的FragmentManager中的beginTransaction
方法創建的。在設置顯示動畫之前,可以根據要求使用add、remove、和replace方法來修改佈局,並設置恰當的back棧行爲。當準備執行改變時,調用commit方法將事務添加到UI隊列。
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// 添加、刪除或者替換Fragment
// 指定動畫
// 如果需要的話,添加到back棧中
fragmentTransaction.commit();
調用 commit()後,事務並不會馬上執行。它會在 activity 的 UI 線程(其實就是主線程)中等待直到線程 能執行的時候才執行(廢話)。如果必要,可以在 UI 線程中調用 fragmentManager.executePendingTransactions()
方法來立即執行事務。
六、添加、刪除和替換Fragment
添加一個新的UIFragment時,需要指定要添加的Fragment實例和將要放置它的容器View。另外,還可以爲這個Fragment指定一個tag標識,後面通過這個標識,可以使用findFragmentByTag
方法找到相應的Fragment。
// 添加Fragment到容器View
fragmentTransaction.add(容器View的id, Fragment實例);
// 添加Fragment到容器View,並給Fragment指定tag
fragmentTransaction.add(容器View的id, Fragment實例, tag);
查找Fragment通常可以通過FragmentManager的findFrafmentById
或者findFragmentByTag
方法來實現:
Fragment fragment_id = fragmentManager.findFragmentById(fragment組件的id);
Fragment fragment_tag = fragmentManager.findFragmentByTag(Fragment實例的tag);
想要刪除一個Fragment,首先需要找到對這個Fragment的引用,然後把找到的Fragment實例作爲參數傳給FragmentTransaction的remove方法。
fragmentTransaction.remove(Fragment實例);
除了添加和刪除操作外,還可以使用replace方法替換Fragment,指定要替換的Fragment的父容器的id、一個新的Fragment和tag標識。
// 替換容器View中的Fragment
fragmentTransaction.replace(容器View的id, Fragment實例);
// 替換容器View中的Fragment,並給新的Fragment指定tag
fragmentTransaction.replace(容器View的id, Fragment實例, tag);
注意:在添加、刪除和替換操作之後,都需要調用fragmentTransaction.commit();
方法提交事務
七、Fragment back棧的管理
假設現在我們有兩個Fragment:Fragment01和Fragment02,我們現在從Fragment01的界面跳到Fragment02,然後按Back鍵,發現程序是直接退出了,而不是返回到Fragment01。如果現在想實現以下功能:從Fragment01的界面跳到Fragment02,然後按Back鍵,會返回到Fragment01。這個功能該怎麼實現呢?這其實就利用到了返回棧的知識。
其實很簡單,FragmentTransaction中提供了一個addToBackStack()方法,可以將一個事務添加到返回棧中。
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// 添加、刪除或者替換Fragment
// 指定動畫
// 添加到back棧中,參數用於描述返回棧的狀態,一般傳null即可
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
八、對Fragment設置切換動畫
FragmentTransaction類中定義了一些默認的動畫,可以對任何FragmentTransaction使用setTransition方法,並傳入一個FragmentTransaction.TRANSIT_*
常量:
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
也可以通過setCustomAnimations
方法對FragmentTransaction設置自定義的動畫:
fragmentTransaction.setCustomAnimations(Fragment進入的動畫資源id, Fragment退出的動畫資源id);