生命周期
使用Fragment時糟需,必要構(gòu)建一個無參構(gòu)造函數(shù)专钉,系統(tǒng)會默認帶。但一但寫有參構(gòu)造函數(shù)复旬,就必要構(gòu)建無參構(gòu)造函數(shù)。一般來說我們傳參數(shù)給Fragment闽巩,會通過bundle驾荣,而不會用構(gòu)造方法傳,代碼如下:
public static MyFragment newInstance(int index){
MyFragment mf = new MyFragment();
Bundle args = new Bundle();
args.putInt("index",index);
mf.setArguments(args);
return mf;
}
(1)onAttach:onAttach()回調(diào)將在Fragment與其Activity關(guān)聯(lián)之后調(diào)用。需要使用Activity的引用或者使用Activity作為其他操作的上下文十办,將在此回調(diào)方法中實現(xiàn)。
需要注意的是:將Fragment附加到Activity以后敦跌,就無法再次調(diào)用setArguments()——除了在最開始,無法向初始化參數(shù)添加內(nèi)容紧憾。
(2)onCreate(Bundle savedInstanceState):此時的Fragment的onCreat回調(diào)時甸赃,該fragmet還沒有獲得Activity的onCreate()已完成的通知胯究,所以不能將依賴于Activity視圖層次結(jié)構(gòu)存在性的代碼放入此回調(diào)方法中株婴。在onCreate()回調(diào)方法中,我們應(yīng)該盡量避免耗時操作姜骡。此時的bundle就可以獲取到activity傳來的參數(shù)
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args != null) {
mLabel = args.getCharSequence("label", mLabel);
}
}
(3)onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState): 其中的Bundle為狀態(tài)包與上面的bundle不一樣。
注意的是:不要將視圖層次結(jié)構(gòu)附加到傳入的ViewGroup父元素中褥伴,該關(guān)聯(lián)會自動完成。如果在此回調(diào)中將碎片的視圖層次結(jié)構(gòu)附加到父元素核芽,很可能會出現(xiàn)異常哮独。
這句話什么意思呢邦泄?就是不要把初始化的view視圖主動添加到container里面站宗,以為這會系統(tǒng)自帶,所以inflate函數(shù)的第三個參數(shù)必須填false益愈,而且不能出現(xiàn)container.addView(v)的操作梢灭。
View v = inflater.inflate(R.layout.hello_world, container, false);
(4)onActivityCreated:onActivityCreated()回調(diào)會在Activity完成其onCreate()回調(diào)之后調(diào)用。在調(diào)用onActivityCreated()之前蒸其,Activity的視圖層次結(jié)構(gòu)已經(jīng)準(zhǔn)備好了敏释,這是在用戶看到用戶界面之前你可對用戶界面執(zhí)行的最后調(diào)整的地方。
強調(diào)的point:如果Activity和她的Fragment是從保存的狀態(tài)重新創(chuàng)建的摸袁,此回調(diào)尤其重要钥顽,也可以在這里確保此Activity的其他所有Fragment已經(jīng)附加到該Activity中了
(5)Fragment與Activity相同生命周期調(diào)用:接下來的onStart()\onResume()\onPause()\onStop()回調(diào)方法將和Activity的回調(diào)方法進行綁定,也就是說與Activity中對應(yīng)的生命周期相同靠汁,因此不做過多介紹蜂大。
(6)onDestroyView:該回調(diào)方法在視圖層次結(jié)構(gòu)與Fragment分離之后調(diào)用。
(7)onDestroy:不再使用Fragment時調(diào)用蝶怔。(備注:Fragment仍然附加到Activity并任然可以找到奶浦,但是不能執(zhí)行其他操作)
(8)onDetach:Fragme生命周期最后回調(diào)函數(shù),調(diào)用后踢星,F(xiàn)ragment不再與Activity綁定澳叉,釋放資源。
Fragment注意事項
在使用Fragment時斩狱,我發(fā)現(xiàn)了一個金礦耳高,那就是setRetainInstance()方法,此方法可以有效地提高系統(tǒng)的運行效率扎瓶,對流暢性要求較高的應(yīng)用可以適當(dāng)采用此方法進行設(shè)置所踊。
Fragment有一個非常強大的功能——就是可以在Activity重新創(chuàng)建時可以不完全銷毀Fragment,以便Fragment可以恢復(fù)概荷。在onCreate()方法中調(diào)用setRetainInstance(true/false)方法是最佳位置秕岛。當(dāng)Fragment恢復(fù)時的生命周期如上圖所示,注意圖中的紅色箭頭。當(dāng)在onCreate()方法中調(diào)用了setRetainInstance(true)后继薛,F(xiàn)ragment恢復(fù)時會跳過onCreate()和onDestroy()方法修壕,因此不能在onCreate()中放置一些初始化邏輯,切忌遏考!
FragmentManager fm = getFragmentManager();
FragmentTransaction tx = fm.beginTransaction();
tx.add(R.id.id_content, new FragmentOne(),"ONE");
tx.addToBackStack(null);
tx.commit();
我們調(diào)用tx.addToBackStack(null)你是否要在回退的時候顯示上一個Fragment慈鸠。
每個Fragment都有一個唯一的TAG或者ID,可以通過getFragmentManager.findFragmentByTag()或者findFragmentById()獲得任何Fragment實例,然后進行操作灌具。
Fragment與Activity通信的最佳實踐
因為要考慮Fragment的重復(fù)使用青团,所以必須降低Fragment與Activity的耦合,而且Fragment更不應(yīng)該直接操作別的Fragment咖楣,畢竟Fragment操作應(yīng)該由它的管理者Activity來決定督笆。
/**
* 交給宿主Activity處理,如果它希望處理
*/
@Override
public void onClick(View v)
{
if (getActivity() instanceof FOneBtnClickListener)
{
((FOneBtnClickListener) getActivity()).onFOneBtnClick();
}
}
DialogFragment
1诱贿、 概述
DialogFragment在android 3.0時被引入娃肿。是一種特殊的Fragment,用于在Activity的內(nèi)容之上展示一個模態(tài)的對話框珠十。典型的用于:展示警告框料扰,輸入框,確認框等等宵睦。
在DialogFragment產(chǎn)生之前记罚,我們創(chuàng)建對話框:一般采用AlertDialog和Dialog。注:官方不推薦直接使用Dialog創(chuàng)建對話框壳嚎。
2桐智、 好處與用法
使用DialogFragment來管理對話框,當(dāng)旋轉(zhuǎn)屏幕和按下后退鍵時可以更好的管理其聲明周期烟馅,它和Fragment有著基本一致的聲明周期说庭。且DialogFragment也允許開發(fā)者把Dialog作為內(nèi)嵌的組件進行重用,類似Fragment(可以在大屏幕和小屏幕顯示出不同的效果)郑趁。上面會通過例子展示這些好處~
使用DialogFragment至少需要實現(xiàn)onCreateView或者onCreateDIalog方法刊驴。onCreateView即使用定義的xml布局文件展示Dialog。onCreateDialog即利用AlertDialog或者Dialog創(chuàng)建出Dialog寡润。
傳統(tǒng)的Dialog旋轉(zhuǎn)屏幕時就消失了捆憎,且后臺log會報異常~~~使用DialogFragment則不受影響。