ViewPager的那些事

目錄:

1、禁止點(diǎn)擊tag時(shí)ViewPager滾動(dòng)的過渡動(dòng)畫。
2、解決adapter的notifyDataSetChanged()無(wú)效問題。
3、設(shè)置ViewPager的預(yù)加載頁(yè)數(shù)。
4、禁止ViewPager手勢(shì)左右切換的操作。
5、ViewPager左右滑動(dòng)的慣性消失的bug。
6、ViewPager與子View進(jìn)行通信。


1、禁止點(diǎn)擊tag時(shí)ViewPager滾動(dòng)的過渡動(dòng)畫:

當(dāng)我們的ViewPager綁定了TabLayout控件的時(shí)候,通常都有點(diǎn)擊一個(gè)tab實(shí)現(xiàn)切換ViewPager的功能,但是如果在切換時(shí)不想要那個(gè)切換動(dòng)畫,該如何做?
解決方案:其實(shí)很簡(jiǎn)單,關(guān)鍵代碼就一句:

//第二個(gè)參數(shù)就是禁止?jié)L動(dòng)過渡的效果
mViewPager.setCurrentItem(0, false);

2、解決adapter的notifyDataSetChanged()無(wú)效問題:

如果想實(shí)現(xiàn)ViewPager的數(shù)據(jù)更新,在調(diào)用adapter的notifyDateSetChanged()會(huì)發(fā)現(xiàn)并沒有效果,其實(shí)并非沒有效果,往后滑動(dòng)兩頁(yè)到第三頁(yè)會(huì)發(fā)現(xiàn),除了ViewPager默認(rèn)緩存的那三頁(yè)數(shù)據(jù)沒有刷新之外,后面的(第三頁(yè)之后)數(shù)據(jù)都是刷新了的,這時(shí)再返回第一頁(yè)會(huì)發(fā)現(xiàn)第一頁(yè)的數(shù)據(jù)也發(fā)生變化了。
解決方案:復(fù)寫adapter的getItemPosition方法,返回POSITION_NONE即可。

public int getItemPosition(Object object) {    
  return POSITION_NONE;
}

存在的問題:這不是PagerAdapter中的Bug,通常情況下,調(diào)用notifyDataSetChanged方法會(huì)讓ViewPager通過Adapter的getItemPosition方法查詢一遍所有child view,這種情況下,所有child view位置均為POSITION_NONE,表示所有的child view都不存在,ViewPager會(huì)調(diào)用destroyItem方法銷毀,并且重新生成,加大系統(tǒng)開銷,并在一些復(fù)雜情況下導(dǎo)致邏輯問題。特別是對(duì)于只是希望更新child view內(nèi)容的時(shí)候,造成了完全不必要的開銷。更有效地方法:更為靠譜的方法是因地制宜,根據(jù)自己的需求來(lái)實(shí)現(xiàn)notifyDataSetChanged的功能,比如,在僅需要對(duì)某個(gè)View內(nèi)容進(jìn)行更新時(shí),在instantiateItem()時(shí),用View.setTag方法加入標(biāo)志,在需要更新信息時(shí),通過findViewWithTag的方法找到對(duì)應(yīng)的View進(jìn)行更新即可。


3、設(shè)置ViewPager的預(yù)加載頁(yè)數(shù):

ViewPager默認(rèn)會(huì)預(yù)加載左右兩頁(yè)的內(nèi)容,如果想預(yù)加載更多,只需調(diào)用ViewPager的setOffscreenPageLimit()即可。

mViewPager.setOffscreenPageLimit(2); // 設(shè)置緩存view 的個(gè)數(shù)(實(shí)際有3個(gè),緩存2個(gè)+正在顯示的1個(gè))

4、禁止ViewPager手勢(shì)左右切換的操作:

解決方案:自定義View繼承自ViewPager,代碼如下:

public class ViewPagerEx extends ViewPager{
    private boolean isPagingEnabled = true;

    public ViewPagerEx(Context context) {
        super(context);
    }
    public ViewPagerEx(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return this.isPagingEnabled && super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return this.isPagingEnabled && super.onInterceptTouchEvent(event);
    }

    public void setPagingEnabled(boolean canScroll) {
        this.isPagingEnabled = canScroll;
    }

    @Override
    public void setCurrentItem(int item, boolean smoothScroll) {
        super.setCurrentItem(item, smoothScroll);
    }
}

使用方法:

mViewPager.setPagingEnabled(false);//禁止左右滑動(dòng)
mViewPager.setPagingEnabled(true);//開啟左右滑動(dòng)
5、ViewPager左右滑動(dòng)的慣性消失的bug。

檢查下FragmentPagerAdapter的構(gòu)造方法是不是傳了getFragmentManager()?如果是,改為getChildFragmentManager()即可,沒錯(cuò),就是這么簡(jiǎn)單。

6、ViewPager與子View進(jìn)行通信。

比如我想在ViewPager每滑動(dòng)結(jié)束后,通知子View并進(jìn)行刷新。

//利用Tag去獲取到對(duì)應(yīng)的子View,然后對(duì)View進(jìn)行操作。
 viewPager.findViewWithTag(position);
//在Adapter的instantiateItem方法中給子View設(shè)置Tag
view.setTag(position);

(不定期更新)

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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