ViewPager默認會緩存1~2個頁面,也就是當前頁面的前一個頁面和後一個頁面,若是後一個頁面不存在,則不在緩存,反之會被緩存java
offscreenPageLimit的默認值爲1android
int offscreenPageLimit = mViewPager.getOffscreenPageLimit(); Log.e("MainActivity", "offscreenPageLimit="+offscreenPageLimit);
1.1輪播圖緩存
有時,須要使用ViewPager+反射勻速Scroller+ImageView作輪播圖時,輪播的圖片超過4個就會出現空白的問題,對於這種問題,明細咱們須要把offscreenPageLimit設置爲n-1,(n爲圖片的個數),這樣把圖片緩存起來(輪播圖通常在首頁,長期存在,所以也就不要想着及時釋放掉這幾張圖片了)性能優化
mViewPager.setOffscreenPageLimit(imageList.size()-1);
ViewPager+Fragment也會受到offscreenPageLimit的影響,對於這個,建議使用n-1模式app
List<BaseFragment> fragmentList = Collections.synchronizedList(new ArrayList<BaseFragment>()); fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(0))); fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(1))); fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(2))); mViewPager.setAdapter(new ViewPagerFragmentAdapter(getSupportFragmentManager())); //CommonFragment是BaseFragment的子類 mViewPager.setOffscreenPageLimit(fragmentList.size()-1); mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){ @Override public void onPageSelected(int position) { super.onPageSelected(position); BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments().get(position); fragment.updateFragment(); } });
固然問題來了,如何每次更新呢,對於這個問題,咱們的解決方案是在BaseFragment中添加以下2個方法以及變量isFirst ide
private boolean isFirst = true; public void updateFragment() { if(isFirst) { isFirst = false; List<Fragment> fragments = getFragmentManager().getFragments(); if(fragments.indexOf(this)!=0) //若是是第一個頁面,第一次調用 { return; } } if(getView()==null) { View decorView = null; if(getActivity()!=null) { decorView = getActivity().getWindow().getDecorView(); } if(decorView!=null) { decorView.postDelayed(new Runnable() { @Override public void run() { updateFragment(); } }, 100); } }else{ onRestart(); } } protected void onRestart() { }
這樣咱們在BaseFragment的子類中重寫onRestart()便可,onRestart在第一次不會調用,這樣就避免了onCreate和onRestart()同時調用一個接口post
如上是一張Fragment生命週期圖,其實不是很完整在 onCreateView---->onStart之間應該是性能
onCreateView->onViewCreated->onActivityCreated->onViewStateRestored->onStart優化
按照咱們Fragment的優化方案,應該分2類優化this
第一類優化(重點改善頁面少,內存,性能要求高的需求)
當咱們使用FragmentTabHost,FragmentPagerAdapter,FragmentTransaction中非replace操做的時候,咱們的優化須要參考
Android Fragment的生命週期和Inflate優化
第二類優化(重點改善頁面多,內存,性能要求高的需求)
當咱們使用的是FragmentStatePagerAdapter或者,FragmentTransaction中的replace操做,咱們須要注意,在生命週期中的
onSaveInstance<------>onViewStateRestored
2個方法,解決咱們開發中,對於頁面不肯定或者頁面較多的問題,相似Activity中的onSaveInstance和onRestoreInstance的用法,經過這種方法,來提升咱們的效率。
android.support.v4.app.Fragment.setUserVisibleHint in Fragment.java on Line 819 android.support.v4.app.FragmentPagerAdapter.setPrimaryItem in FragmentPagerAdapter.java on Line 130
對於如上問題,咱們須要FragmentStatePagerAdapter替換FragmentPagerAdapter