Android应用开发—ViewPager FragmentPagerAdapter和FragmentStatePagerAdapter下Fragment的生命周期
ViewPager配合不同的PagerAdapter,對(duì)應(yīng)Fragment的生命周期有著不同的表現(xiàn),了解這個(gè)生命周期機(jī)制對(duì)于開(kāi)發(fā)者選擇合適的PagerAdapter實(shí)現(xiàn)不同的效果,有著很大的幫助。
FragmentPagerAdapter和FragmentStatePagerAdapter的區(qū)別:
- FragmentPagerAdapter:
類內(nèi)的每一個(gè)生成的 Fragment
都將保存在內(nèi)存之中,因此適用于那些相對(duì)靜態(tài)的頁(yè),數(shù)量也比較少的那種;如果需要處理有很多頁(yè),并且數(shù)據(jù)動(dòng)態(tài)性較大、占用內(nèi)存較多的情況,應(yīng)該使用FragmentStatePagerAdapter。 - FragmentStatePagerAdapter:
正如其類名中的 ‘State’ 所表明的含義一樣,該 PagerAdapter
的實(shí)現(xiàn)將只保留當(dāng)前頁(yè)面,當(dāng)頁(yè)面離開(kāi)視線后,就會(huì)被消除,釋放其資源; 而在頁(yè)面需要顯示時(shí),生成新的頁(yè)面(就像 ListView的實(shí)現(xiàn)一樣)。這么實(shí)現(xiàn)的好處就是當(dāng)擁有大量的頁(yè)面時(shí),不必在內(nèi)存中占用大量的內(nèi)存。
viewPager.setOffscreenPageLimit(X)對(duì)Fragment創(chuàng)建時(shí)機(jī)的影響:
如果ViewPager下有N個(gè)fragments,并設(shè)置了setOffscreenPageLimit(X),則當(dāng)fragment1用戶可見(jiàn)時(shí),其后面X個(gè)fragment也已經(jīng)同fragment1一同預(yù)先創(chuàng)建完成。當(dāng)滑動(dòng)fragment1->fragment2時(shí),第X+2個(gè)fragment完成創(chuàng)建,以保持當(dāng)前fragment(fragment2)后有X個(gè)fragment已經(jīng)創(chuàng)建完成作為緩存。
- FragmentPagerAdapter和FragmentStatePagerAdapter差別:
如前面提到FragmentPagerAdapter不會(huì)釋放創(chuàng)建過(guò)的fragment,這樣當(dāng)fragment1->fragmentN完成以輪切換后,從fragmentN->fragment1反方向切換時(shí),不會(huì)再觸發(fā)fragment的創(chuàng)建,即onCreate()不會(huì)被調(diào)用。
而FragmentStatePagerAdapter做從fragmentN->fragment1反方向切換時(shí)則會(huì)繼續(xù)觸發(fā)fragment的創(chuàng)建以保障有X個(gè)fragment被創(chuàng)建并緩存著(因?yàn)榇笥赬的fragment已經(jīng)被釋放了)
總結(jié):fragment的onCreate()總是預(yù)先被調(diào)用,且被調(diào)用的時(shí)機(jī)總是同當(dāng)前用戶可見(jiàn)的fragment保持X個(gè)fragment的“距離“,即某個(gè)fragment的onCreate()被調(diào)用時(shí),它的前X個(gè)fragment是用戶可見(jiàn)的。
奇怪的onResume():前面說(shuō)明了onCreate()被觸發(fā)的規(guī)律,但是onResume()的觸發(fā)規(guī)律則十分奇怪,eg:有以下fragment,f1,f2,f3,f4當(dāng)f1->f2時(shí),f2的onResume()被觸發(fā),當(dāng)f2->f3時(shí),f3的onResume()被觸發(fā),當(dāng)f3->f2時(shí),f2的onResume()不會(huì)被觸發(fā),當(dāng)f2->f3時(shí),f3的onResume()仍然被觸發(fā),鑒于這個(gè)onResume()被觸發(fā)的規(guī)律很“混亂”,所以不宜做一些需要確定性的任務(wù)。(后面有機(jī)會(huì)在研究下了)
實(shí)際應(yīng)用:
當(dāng)fragment切換至用戶可見(jiàn)后,要做一些處理,比如請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù),更新當(dāng)前頁(yè)面等。
經(jīng)過(guò)前面的分析可知onCreate()和onResume()的觸發(fā)時(shí)機(jī)都不滿足以上要求:onCreate()會(huì)預(yù)創(chuàng)建,FragmentPagerAdapter下還會(huì)一直緩存,onResume()的觸發(fā)時(shí)機(jī)又沒(méi)有規(guī)律(正常情況下大家對(duì)于這種需求一般會(huì)想到resume()這類接口)。
我們可以利用setUserVisibleHint()接口實(shí)現(xiàn)該功能,即當(dāng)本fragment為用戶可見(jiàn)時(shí),該接口被觸發(fā),以達(dá)到每次fragment切換為可見(jiàn)后,更新當(dāng)前fragment頁(yè)面數(shù)據(jù)的目的。
實(shí)現(xiàn)類似網(wǎng)易新聞客戶端,ViewPager每次只加載當(dāng)前頁(yè)。
如前所訴,使用FragmentPagerAdapter或者FragmentStatePagerAdapter都會(huì)默認(rèn)多加載X頁(yè)(X通過(guò)setOffscreenPageLimit()設(shè)置,最小值為1)。
這個(gè)需求同樣通過(guò)setUserVisibleHint()來(lái)實(shí)現(xiàn),將網(wǎng)絡(luò)請(qǐng)求加載頁(yè)面的處理,從onCreate()中移到setUserVisibleHint()中,這樣就實(shí)現(xiàn)了切換到頁(yè)面才進(jìn)行更新的效果。
notes:貌似在某些廠商的rom上對(duì)FragmentPagerAdapter的緩存機(jī)制做了改動(dòng),導(dǎo)致緩存失效,這樣就要十分小心對(duì)緩存fragment生命周期的處理,盡量避免引用不在前臺(tái)展示的fragment。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Android应用开发—ViewPager FragmentPagerAdapter和FragmentStatePagerAdapter下Fragment的生命周期的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android应用开发-onNewInt
- 下一篇: 两性位置