ViewPager頁面懶加載與緩存頁面數量可控

ViewPager頁面懶加載與緩存頁面數量可控java


本文目標:
1.    實現ViewPager的頁面懶加載;
在某些狀況下,例如使用ViewPager查看多張大圖,此時多張圖片不能一次性載入,只有在瀏覽該頁面時才載入(或者預先載入下一頁面)頁面的具體內容。
2.    可控ViewPager緩存頁面的數量。
常見的狀況:1.頁面的總數是已知的,或者能夠計算出來,每一個頁面佔用的資源並很少而且須要常用這些頁面。這是能夠考慮將其常駐ViewPager而不去銷燬(頻繁的銷燬和重建也會消耗比較多的資源)。2.切換頁面時默認狀況下非相鄰的頁面會被銷燬掉(ViewPager默認緩存或預加載相鄰的頁面以便快速切換),若是想要保持頁面以前的狀態,如滾動條滾動位置等比較困難;這是能夠考慮將以前的頁面緩存下來而不銷燬掉。
ViewPager的默認加載與緩存模式
ViewPager和ListView、GridView等的數據加載方式相似,控件自己都提供了數據加載的適配器接口,程序員只需實現特定的Adapter就能夠輕鬆的將數據填充到容器中。
咱們來看一個簡單的Demo
1.ViewPager懶加載和緩存測試類
android

package com.example.viewpagertest;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
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的頁面實例化的時候加載數據,預加載的時候也會執行該方法。
app

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:當該頁面被選中的時候才加載該頁面的數據,預加載頁面時不會加載預加載頁的數據。
ide

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頁面不會被銷燬。

this

相關文章
相關標籤/搜索