ViewPager的緩存機制


1.實現Viewpager的頁面懶加載:

在某些情況下,例如使用ViewPager查看多張大圖,此時多張圖片不能一次性載入,只有在瀏覽該頁面時才載入(或者預先載入下一頁面)頁面的具體內容。

2.可控Viewpager緩存頁面的數量:

常見的情況:

(1)頁面的總數是已知的,或者可以計算出來,每個頁面占用的資源並不多並且需要經常使用這些頁面。這時可以考慮將其常駐ViewPager而不去銷毀(頻繁的銷毀和重建也會消耗比較多的資源)。

(2)切換頁面時默認情況下非相鄰的頁面會被銷毀掉(ViewPager默認緩存或預加載相鄰的頁面以便快速切換),如果想要保持頁面之前的狀態,如滾動條滾動位置等比較困難;這時可以考慮將之前的頁面緩存下來而不銷毀掉。

 

ViewPager的默認加載與緩存模式

ViewPager和ListView、GridView等的數據加載方式類似,控件本身都提供了數據加載的適配器接口,程序員只需實現特定的Adapter就可以輕松的將數據填充到容器中。

我們來看一個簡單的Demo。

1.ViewPager懶加載和緩存測試類

public class MainActivity extends Activity {  
    private static final String TAG = "com.example.viewpagertest.MainActivity";  
    private MyViewPager viewPager;  
    private List<View> pagers = new ArrayList<View>();  
    /** ViewPager緩存頁面數目;當前頁面的相鄰N各頁面都會被緩存 */  
    private int cachePagers = 1;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        getViews();  
        setContentView(viewPager);  
        setListener();  
        setAdapter();  
    }  
    private void getViews() {  
        viewPager = new MyViewPager(this);  
        for (int i = 0; i < 5; i++) {  
            TextView textView = new TextView(this);  
            pagers.add(textView);  
            viewPager.onDisplay(i);//測試1  
        }  
        viewPager.setOffscreenPageLimit(cachePagers);// 設置緩存頁面,當前頁面的相鄰N各頁面都會被緩存  
    }  
    private void setAdapter() {  
        viewPager.setAdapter(pagerAdapter);  
    }  
    private void setListener() {  
        viewPager.setOnPageChangeListener(pageChangeListener);  
    }  
    /** 
     * 頁面數據適配器 
     */  
    private PagerAdapter pagerAdapter = new PagerAdapter() {  
        @Override  
        public void destroyItem(View container, int position, Object object) {  
            Log.i(TAG, "destroyItem:" + position);  
            ((ViewGroup) container).removeView((View) object);  
        }  
        @Override  
        public void destroyItem(ViewGroup container, int position, Object object) {  
            Log.i(TAG, "destroyItem:" + position);  
            container.removeView((View) object);  
        }  
        @Override  
        public Object instantiateItem(View container, int position) {  
            Log.i(TAG, "instantiateItem:" + position);  
            try {  
                ((ViewPager) container).addView(pagers.get(position));  
                // ((MyViewPager) container).onDisplay(position);//測試2  
            } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
            }  
            return pagers.get(position);  
        }  
        @Override  
        public Object instantiateItem(ViewGroup container, int position) {  
            Log.i(TAG, "instantiateItem:" + position);  
            try {  
                ((ViewPager) container).addView(pagers.get(position));  
                // ((MyViewPager) container).onDisplay(position);//測試2  
            } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
            }  
            return pagers.get(position);  
        }  
        @Override  
        public boolean isViewFromObject(View arg0, Object arg1) {  
            return arg0 == arg1;  
        }  
        @Override  
        public int getCount() {  
            return pagers.size();  
        }  
    };  
    /** 
     * 頁面滾動監聽器 
     */  
    private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {  
        @Override  
        public void onPageSelected(int arg0) {  
            Log.i(TAG, "onPageSelected:" + arg0);  
            // viewPager.onDisplay(arg0);//測試3  
        }  
        @Override  
        public void onPageScrolled(int arg0, float arg1, int arg2) {  
        }  
        @Override  
        public void onPageScrollStateChanged(int arg0) {  
        }  
    };  
    /** 
     * @Title setPageData 
     * @Description 加載頁面數據 
     * @param position 
     */  
    private void setPageData(int position) {  
        TextView textView = (TextView) pagers.get(position);  
        textView.setText("pager" + position);  
        Log.i(TAG, "setPageData position:" + position);  
    }  
    class MyViewPager extends ViewPager implements IPagerDisplay {  
        public MyViewPager(Context context) {  
            super(context);  
        }  
        public MyViewPager(Context context, AttributeSet attrs) {  
            super(context, attrs);  
        }  
        @Override  
        public void onDisplay(int position) {  
            setPageData(position);  
        }  
    }  
}  

2.ViewPager數據展示回調接口

/** 
 * @Title IPagerDisplay.java 
 * @Package com.example.viewpagertest 
 * @Description ViewPager數據展示回調 
 * @author ze.chen 
 * @date 2013-5-13 下午2:25:38 
 * @version V1.0 
 */  
package com.example.viewpagertest;  
/** 
 * @ClassName IPagerDisplay 
 * @Description ViewPager懶加載展接口;可以在PagerAdapter的instantiateItem時候調用, 
 *              亦可以在OnPageChangeListener的onPageSelected時候調用 
 *              ,兩處的區別在於,instantiateItem方法ViewPager會自動緩沖 
 *              (瀏覽pager1時將pager2的數據加載好), 
 *              而onPageSelected則不會自動緩沖(瀏覽pager2時才加載pager2的數據) 
 * @author ze.chen 
 * @date 2013-5-13 下午2:25:38  
 * 
 */  
public interface IPagerDisplay {  
    void onDisplay(int position);  
}  

使ViewPager支持懶加載

在以上代碼段中,分別注釋了:測試1;測試2;測試3。

測試1:在加載ViewPager之前,初始化所有的頁面和數據。

viewPager = new MyViewPager(this);  
        for (int i = 0; i < 5; i++) {  
            TextView textView = new TextView(this);  
            pagers.add(textView);  
            viewPager.onDisplay(i);//測試1  
        } 

對於測試2和測試3,只將控件添加到pagers列表中,數據不立刻加載
測試2:在ViewPager的頁面實例化的時候加載數據,預加載的時候也會執行該方法。

public Object instantiateItem(View container, int position) {  
            Log.i(TAG, "instantiateItem:" + position);  
            try {  
                ((ViewPager) container).addView(pagers.get(position));  
                ((MyViewPager) container).onDisplay(position);//測試2  
            } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
            }  
            return pagers.get(position);  
        }  

測試3:當該頁面被選中的時候才加載該頁面的數據,預加載頁面時不會加載預加載頁的數據。

private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {  
        @Override  
        public void onPageSelected(int arg0) {  
            Log.i(TAG, "onPageSelected:" + arg0);  
            viewPager.onDisplay(arg0);//測試3  
        }  
……  

修改ViewPager的緩存頁面數量

viewPager.setOffscreenPageLimit(int numbers); 

viewpager當前頁面兩側緩存/預加載的頁面數目。當頁面切換時,當前頁面相鄰兩側的numbers頁面不會被銷毀。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM