Fragment
fragment本來設計的初中是爲了適應大屏幕的平板電腦,現在我們普通的手機開發也會加入這個Fragment,我們可以把他理解爲小型的Activity,但是他還是必須嵌套在Activity裏使用的,所以我們可以按照直譯去理解他——Activity的一個“碎片”。雖然fragment有自己的生命週期,但是還是會受到宿主Activity的影響。
生命週期
FragmentManager
這裏說一下,fragment目前有兩種,一個是v4包的fragment,還一個是原生的fragment,所以fragmentManager的獲取方式也有兩種:
- getSupportFragmentManager() 用於v4包獲取fragmentManager
- getFragmentManager() 用於app包的Fragment獲取Fragmentmanager
FragmentManager用來處理fragment的一部分操作
- 使用findFragmentById()或findFragmentByTag()方法,得到Activity中存在的fragment,也可判斷Ativity中發fragment是否爲空。
- popBackStack():將back stack中最後一次的fragment轉換彈出。如果沒有可以出棧的東西,返回false。
FragmentTransaction
這個是具體處理Fragment事務的類,可以執行一些操作例如對fragment增加,刪除,替換,隱藏的這些操作
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, newFragment);//添加一個fragment
transaction.replace(R.id.fragment_container, new2Fragment);//替換一個fragment
transaction.hide(newFragment);//隱藏一個fragment
transaction.remove(newFragment);//刪除一個fragment
transaction.addToBackStack(null);加入BACK棧
transaction.commit();//提交事務操作
關於commit方法
- 調用commit方法並不是立即執行transaction中包含的改變動作,commit方法吧transaction加入activity的UI線程隊列中
- 你只能在activity儲存它的狀態之前調用commit,如果在儲存狀態之後調用將會拋出異常(儲存狀態:也就是用戶離開activity,saveInstanceStates的時候)
關於add和replace的性能
fragment替換的方式有兩種:
1. add進來 然後 hide調再add一個新的fragment,當想切回之前的fragment的時候hide掉新的fragment,show舊的fragment。
2. add進來,然後replace成新的fragment,當想切回去的時候繼續repalce成舊的
之前找到一個博客顯示了這兩種方式的性能比:
add方式
replace方式
所以 如果想提升性能的話 儘量使用add方式添加fragment
封裝一個添加和切換的方法:
/**
* 添加/或展示一個fragment
* @param fragment 想要添加/展示的fragment
* @param id 佔位佈局的ID
* @param tag 打一個T啊,需要用這個Tag去搜索是否存在這個fragment
*/
private <T extends Fragment> void addNewFragment( T fragment, int id, String tag) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//優先檢查,fragment是否存在,避免重疊
T tempFragment = (T)fragmentManager.findFragmentByTag(tag);
if (tempFragment != null) {
fragment = tempFragment;
}
if (fragment.isAdded()) {
addOrShow(fragmentTransaction, fragment, id, tag);
} else {
if (currentFragment != null && currentFragment.isAdded()) {
fragmentTransaction.hide(currentFragment).add(id, fragment, tag).commit();
} else {
fragmentTransaction.add(id, fragment, tag).commit();
}
currentFragment = fragment;
}
}
/**
* 添加/展示fragment方法
* @param transaction fragment處理事務
* @param fragment 想要添加/展示的fragment
* @param id 佔位佈局的ID
* @param tag fragment查詢標識
*/
private <T extends Fragment> void addOrShow(FragmentTransaction transaction, T fragment, int id, String tag) {
if (currentFragment == fragment)
return;
if (!fragment.isAdded()) { // 如果當前fragment未被添加,則添加到Fragment管理器中
transaction.hide(currentFragment).add(id, fragment, tag).commit();
} else {
transaction.hide(currentFragment).show(fragment).commit();
}
currentFragment.setUserVisibleHint(false);
currentFragment = fragment;
currentFragment.setUserVisibleHint(true);
}
這裏講解一下
首先我們傳進來的是 Fragment的子類 用了個泛型(其實這裏傳一個Fragment也可以,我覺得我好像有點多此一舉)
接下來,看流程:
這樣一來,不管你替換什麼fragment,只要調用這個方法,就會使用Add方式替換fragment了(這流程挺簡單的一看就懂,要是看不懂,直接粘代碼簡單粗暴)
結語
其他的我就不多講了,到這裏爲止就可以初步的使用fragment了,至於更深層的東西希望大家多思考,編程嘛,水深得很,總有更屌的方法,更靈活的方法,更貼近業務的方法,所以,學無止境 !