FragmentPagerAdapter與FragmentStatePagerAdapter區(qū)別

轉(zhuǎn)自aitian

ViewPager

ViewPager 如其名所述,是負(fù)責(zé)翻頁(yè)的一個(gè) View。準(zhǔn)確說(shuō)是一個(gè) ViewGroup,包含多個(gè) View 頁(yè),在手指橫向滑動(dòng)屏幕時(shí),其負(fù)責(zé)對(duì) View 進(jìn)行切換。為了生成這些 View 頁(yè),需要提供一個(gè) PagerAdapter 來(lái)進(jìn)行和數(shù)據(jù)綁定以及生成最終的 View 頁(yè)。

  • setAdapter()

ViewPager 通過(guò) setAdapter() 來(lái)建立與 PagerAdapter 的聯(lián)系。這個(gè)聯(lián)系是雙向的,一方面,ViewPager 會(huì)擁有 PagerAdapter 對(duì)象,從而可以在需要時(shí)調(diào)用 PagerAdapter 的方法;另一方面,ViewPager 會(huì)在 setAdapter() 中調(diào)用 PagerAdapter 的 registerDataSetObserver() 方法,注冊(cè)一個(gè)自己生成的 PagerObserver 對(duì)象,從而在 PagerAdapter 有所需要時(shí)(如 notifyDataSetChanged()或 notifyDataSetInvalidated() 時(shí)),可以調(diào)用 Observer 的 onChanged() 或 onInvalidated() 方法,從而實(shí)現(xiàn) PagerAdapter 向 ViewPager 方向發(fā)送信息。

  • dataSetChanged()

在 PagerObserver.onChanged(),以及 PagerObserver.onInvalide() 中被調(diào)用。因此當(dāng) PagerAdapter.notifyDataSetChanged() 被觸發(fā)時(shí),ViewPager.dataSetChanged() 也可以被觸發(fā)。該函數(shù)將使用 getItemPosition() 的返回值來(lái)進(jìn)行判斷,如果為 POSITION_UNCHANGED,則什么都不做;如果為 POSITION_NONE,則調(diào)用 PagerAdapter.destroyItem() 來(lái)去掉該對(duì)象,并設(shè)置為需要刷新 (needPopulate = true) 以便觸發(fā)PagerAdapter.instantiateItem() 來(lái)生成新的對(duì)象。

PagerAdapter

PageAdapter 是 ViewPager 的支持者,ViewPager 將調(diào)用它來(lái)取得所需顯示的頁(yè),而 PageAdapter 也會(huì)在數(shù)據(jù)變化時(shí),通知 ViewPager。這個(gè)類(lèi)也是FragmentPagerAdapter 以及 FragmentStatePagerAdapter 的基類(lèi)。如果繼承自該類(lèi),至少需要實(shí)現(xiàn) instantiateItem(), destroyItem(), getCount() 以及 isViewFromObject()。

  • instantiateItem( )
    在每次 ViewPager 需要一個(gè)用以顯示的 Object 的時(shí)候,該函數(shù)都會(huì)被 ViewPager.addNewItem() 調(diào)用。

FragmentPagerAdapter

FragmentPagerAdapter 繼承自 PagerAdapter。相比通用的 PagerAdapter,該類(lèi)更專(zhuān)注于每一頁(yè)均為 Fragment 的情況。如文檔所述,該類(lèi)內(nèi)的每一個(gè)生成的 Fragment 都將保存在內(nèi)存之中,因此適用于那些相對(duì)靜態(tài)的頁(yè),數(shù)量也比較少的那種如果需要處理有很多頁(yè),并且數(shù)據(jù)動(dòng)態(tài)性較大、占用內(nèi)存較多的情況,應(yīng)該使用FragmentStatePagerAdapter。FragmentPagerAdapter 重載實(shí)現(xiàn)了幾個(gè)必須的函數(shù),因此來(lái)自 PagerAdapter 的函數(shù),我們只需要實(shí)現(xiàn) getCount(),即可。且,由于 FragmentPagerAdapter.instantiateItem() 的實(shí)現(xiàn)中,調(diào)用了一個(gè)新增的虛函數(shù) getItem(),因此,我們還至少需要實(shí)現(xiàn)一個(gè) getItem()。因此,總體上來(lái)說(shuō),相對(duì)于繼承自 PagerAdapter,更方便一些。

FragmentStatePagerAdapter

FragmentStatePagerAdapter 和前面的 FragmentPagerAdapter 一樣,是繼承子 PagerAdapter。但是,和 FragmentPagerAdapter 不一樣的是,正如其類(lèi)名中的 '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)存。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容