ViewPager 重新可見時bug
-
項目場景
最近項目正在做自動輪播的banner效果,出現(xiàn)了幾種意想不到的問題。
1:由于banner是放在recyclerview 中的head中,所有當滑動recyclerview 至banner到屏幕外再回來,
會發(fā)現(xiàn),viewpager第一次切換pager 無動畫效果,也就是翻頁速度很快。
2:當從別的fragment頁面中切換到有banner的fragment中的時候,也就是banner中的fragment由
isVisibleToUser=false 變成 isVisibleToUser=true時 會出現(xiàn)viewpager中兩個pager卡著不動,過段時間才會恢復并且切換無動畫
-
bug背景
當ViewPager不可見時,會執(zhí)行其onDetachedFromWindow方法,再次可見時會執(zhí)行onAttachedToWindow方法,這時候會出現(xiàn)以下bug:
-
1.在Android4.0上會出現(xiàn)第一次自動滑動沒有動畫效果。
-
2.在Android5.0上會出現(xiàn)第一次滑動不僅沒有動畫效果,而且連View都沒有。
-
3.當ViewPager自動滑動到一半的時候,將其隱藏后,無法自動滑完。會出現(xiàn)滑一半的情況。
-
bug原因
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mFirstLayout = true;
}
void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {
.....\\省略部分代碼
if (mFirstLayout) {
// We don't have any idea how big we are yet and shouldn't have any pages either.
// Just set things up and let the pending layout handle things.
mCurItem = item;
if (dispatchSelected) {
dispatchOnPageSelected(item);
}
requestLayout();
} else {
populate(item);
scrollToItem(item, smoothScroll, velocity, dispatchSelected);
}
}
WTF!!!! 細看
viewpager 源碼中有個mFirstLayout 成員變量,當mFirstLayout=true時,是不走scrollToItem方法的,
所以會導致頁面重新可見時,第一次切換是沒有動畫的!?。。。。。。。。。。?!
-
解決辦法
繼承viewpager 重寫 onAttachedToWindow()方法,反射mFirstLayout 成員變量 修改值
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
/**
* 設ViewPager中有3張照片
* 直到完全隱藏此ViewPager,并執(zhí)行了onDetachedFromWindow
* 再回來時,將會出現(xiàn)bug,第一次滑動時沒有動畫效果,并且,經(jīng)常出現(xiàn)view沒有加載的情況
*/
try {
Field mFirstLayout = ViewPager.class.getDeclaredField("mFirstLayout");
mFirstLayout.setAccessible(true);
mFirstLayout.set(this, false);
setCurrentItem(getCurrentItem());
} catch (Exception e) {
e.printStackTrace();
}
}