目錄:
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);
(不定期更新)