Fragment翻譯過(guò)來(lái)就是碎片的意思姚建,他能夠作為一個(gè)組件的存在呐舔,拼湊出一個(gè)界面來(lái)币励,意味著activity很多部分可以抽成一個(gè)個(gè)碎片,以便能夠復(fù)用珊拼。
關(guān)于fragment的生命周期食呻,用一張圖來(lái)展示就可以了。
以下說(shuō)一些重點(diǎn):
1.Fragment在onAttach 開始跟Activity window綁定澎现,這個(gè)時(shí)候 就已經(jīng)可以通過(guò)getActivity來(lái)拿到activity實(shí)例了搁进。
2.fragment去inflate一個(gè)xml一般在onCreateView那邊 ,不過(guò)也可以在onCreate里面inflate昔头,然后在onCreateView去return ,這取決于你的想法影兽,跟界面的布局揭斧。
3.fragment跟activity綁定后,他的生命周期依賴于activity峻堰,那么意味著讹开,activity中有多個(gè)fragment,通過(guò)viewpager和其adapter進(jìn)行控制捐名,當(dāng)hide一個(gè)fragment旦万,show一個(gè)fragment時(shí),他的onResume方法可能不會(huì)被調(diào)用镶蹋,因?yàn)闆](méi)有影響到activity的生命周期。
4.在生命周期方面,activity和fragment之間一個(gè)很重要的不同就是在各自的后臺(tái)棧中是如何存儲(chǔ)的砌左。當(dāng)activity停止時(shí)住闯,默認(rèn)情況下activity被安置在由系統(tǒng)管理的activity后臺(tái)棧中;fragment僅當(dāng)在一個(gè)事務(wù)被移除時(shí)拂酣,通過(guò)顯式調(diào)用addToBackStack()請(qǐng)求保存的實(shí)例秋冰,該fragment才被置于由宿主activity管理的后臺(tái)棧。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment,
container, false);
}
inflate()函數(shù)需要以下三個(gè)參數(shù):
(1).要inflate的布局的資源Id
(2).被inflate的布局的父ViewGroup
(3).一個(gè)布爾值婶熬,表明在inflate期間被inflate的布局是否應(yīng)該附上ViewGroup(第二個(gè)參數(shù)container)剑勾。(在這個(gè)例子中傳入的是false,因?yàn)橄到y(tǒng)已經(jīng)將被inflate的布局插入到容器中(container)——傳入true會(huì)在最終的布局里創(chuàng)建一個(gè)多余的ViewGroup)
5.在android中赵颅,對(duì)fragment的事務(wù)操作都是通過(guò)FragmentTranSaction來(lái)執(zhí)行虽另。操作大致可以分為兩類:
1:>顯示:add(), replace(), show(), attach()
2:>隱藏:remove(), hide(), detach()
說(shuō)明:調(diào)用show() & hide()方法時(shí),F(xiàn)ragment的生命周期方法并不會(huì)被執(zhí)行性含,僅僅是Fragment的View被顯示或者?隱藏洲赵。執(zhí)行replace()時(shí)(至少兩個(gè)Fragment),會(huì)執(zhí)行第二個(gè)Fragment的onAttach()方法、執(zhí)行第一個(gè)Fragment的onPause()-onDetach()方法叠萍,同時(shí)containerView會(huì)detach第一個(gè)Fragment的View芝发。add()方法執(zhí)行onAttach()-onResume()的生命周期,相對(duì)的remove()就是執(zhí)行完成剩下的onPause()-onDetach()周期苛谷。
6.關(guān)于onSaveInstanceState(Bundle outState),此方法是在fragment或者activity可能被銷毀的情況下 辅鲸,就會(huì)被調(diào)用,即系統(tǒng)不清楚你的這次操作會(huì)不會(huì)帶來(lái)銷毀的結(jié)果腹殿,那么就會(huì)調(diào)用這個(gè)方法独悴,比如按home鍵,界面跳轉(zhuǎn) 等锣尉,并且 onRestoreInstanceState方法并不是一定對(duì)應(yīng)的刻炒,意味著 前者被執(zhí)行后,后者并不一定會(huì)被執(zhí)行到自沧。
7.對(duì)于一些外界傳進(jìn)來(lái)的參數(shù)坟奥,記得用onSaveInstanceState保存一下,不然內(nèi)存不足的情況下拇厢,很容易被回收掉爱谁,導(dǎo)致參數(shù)不存在,而顯示空白孝偎。
8.FragmentTransaction 可以做fragment的替換访敌,獲取事物之后,還可以設(shè)置 進(jìn)出的動(dòng)畫衣盾。還有在調(diào)用commit()之前寺旺,可以將事務(wù)添加到fragment事務(wù)后臺(tái)棧中(通過(guò)調(diào)用addToBackStatck())。這個(gè)后臺(tái)棧由activity管理雨效,并且允許用戶通過(guò)按BACK鍵回退到前一個(gè)fragment狀態(tài)迅涮。
當(dāng)移除一個(gè)fragment時(shí),如果調(diào)用了addToBackStack()徽龟,那么之后fragment會(huì)被停止叮姑,如果用戶回退,它將被恢復(fù)過(guò)來(lái)据悔。
調(diào)用commit()并不立刻執(zhí)行事務(wù)传透,相反,而是采取預(yù)約方式极颓,一旦activity的界面線程(主線程)準(zhǔn)備好便可運(yùn)行起來(lái)朱盐。然而,如果有必要的話菠隆,你可以從界面線程調(diào)用executePendingTransations()立即執(zhí)行由commit()提交的事務(wù)兵琳。
9.下面的代碼中一個(gè)fragment代替另一個(gè)fragment狂秘,并且將之前的fragment狀態(tài)保留在后臺(tái)棧中:
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
10.只能在activity保存狀態(tài)(當(dāng)用戶離開activity時(shí))之前用commit()提交事務(wù)。如果你嘗試在那時(shí)之后提交躯肌,會(huì)拋出一個(gè)異常者春。這是因?yàn)槿绻鸻ctivity需要被恢復(fù),提交后的狀態(tài)會(huì)被丟失清女。對(duì)于這類丟失提交的情況钱烟,可使用commitAllowingStateLoss()。
11.管理Fragment回退棧
跟蹤回退棧的狀態(tài)
我們通過(guò)實(shí)現(xiàn)OnBackStackChangedListener接口來(lái)實(shí)現(xiàn)回退棧狀態(tài)跟蹤嫡丙,具體代碼如下:
//implements接口
public class XXX implements FragmentManager.OnBackStackChangedListener
//實(shí)現(xiàn)接口所要實(shí)現(xiàn)的方法
@Override
public void onBackStackChanged() {
//do whatevery you want
}
//設(shè)置回退棧監(jiān)聽接口
getSupportFragmentManager().addOnBackStackChangedListener(this);
管理回退棧
(1).FragmentTransaction.addToBackStack(String)
將一個(gè)剛剛添加的Fragment加入到回退棧中
(2).getSupportFragmentManager().getBackStackEntryCount()
獲取回退棧中的實(shí)體數(shù)量
(3).getSupportFragmentManager().popBackStack(String name, int flags)
根據(jù)name立刻彈出棧頂?shù)膄ragment
(4).getSupportFragmentManager().popBackStack(int id, int flags)
根據(jù)id立刻彈出棧頂?shù)膄ragment