ViewPager+Fragment使用setCurrentItem
最近在一個考試系統,需求是做100道題,可以左右翻頁,右上角有個彈窗標記之前做的題的對錯、總提數、當前在那道題,點擊可以跳轉對應的那道題。先看下效果圖
需求大概就是這樣的;運到的問題就是當做了十幾道題之後,點擊彈窗點第一道題可以正常跳轉到第一題,之後在點擊第十題後跳轉到第十題,
界面出現的空白
,稍微滑動下屏幕界面就出來了。
問題大概描述了下,分析下原因,都知道viewPager是有緩存機制的,在代碼中可以用
setOffscreenPageLimit
設置緩存界面的數量,一般我們使用viewPager+Fragmnet的時候數量不超過十個,所以設置setOffscreenPageLimit(10)
對現在大內存手機來說影響並不是很大;我這個需求是做題,題目的數量不確定,但是肯定會有很多道,當我把setOffscreenPageLimit()
數量設置爲list.size()
時就不會出現問題,但是對內存消耗很大,這種方法肯定是行不通的。
還有一種方法也可以解決,就是設置setCurrentItem(position,true)把第二個參數設爲true,也不會出現白屏的問題,但是就是會有翻頁的動畫,當翻頁數量過多時比較耗時,而且用戶的體驗也不是很好。
還試了一種方法,網上的找到,在我的項目中沒有起到作用,需求跟我的差不多,但是在我這裏不起作用。
連接
問題應該就是viewPager緩存機制導致的,出現白屏可能是視圖沒有及時刷新,所以用new Handler延遲刷新,也是沒用。
弄了一天沒搞出來,頭都快炸了~
最後在同事的提示下,想到了,可能是View疊加了,之前的view並沒有銷燬導致的,仔細一想說的好像有道理,於是動手在onCreateView
的return view之前做了判斷代碼如下:
private View rootView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_brushing, container, false);
}
//緩存的rootView需要判斷是否已經被加過parent, 如果有parent則從parent刪除,防止發生這個rootview已經有parent的錯誤。
ViewGroup mViewGroup = (ViewGroup) rootView.getParent();
if (mViewGroup != null) {
mViewGroup.removeView(rootView);
}
initView(rootView);
return rootView;
}
使用FragmentPagerAdapter只會走onDestroyView
並不會銷燬Fragment,在此加了一個rootView來判斷之前加載的視圖是否爲空,不爲空移除parent(不移除會報錯)直接用,刷新下數據即可,沒有才去創建新的,這樣一來可以防止重複創建view導致空白的問題。這個對內存消耗也不是很大。至此我的問題就解決的。如果你遇到的問題跟我差不多也是試試這種方法。