ViewPager系列文章(一)- ViewPager源码分析及加载页面原理图

1. ViewPager源码分析

1>:点击 viewPager.setAdapter进入下边源码,会调用 populate() 方法,这个方法作用是创建和销毁子条目(子item):

/**
     * Set a PagerAdapter that will supply views for this pager as needed.
     *
     * @param adapter Adapter to use
     */
    public void setAdapter(PagerAdapter adapter) {
         populate();
    }
void populate(int newCurrentItem) {
        if (curItem == null && N > 0) {
            // 创建item
            curItem = addNewItem(mCurItem, curIndex);
        }
       if (pos == ii.position && !ii.scrolling) {
             // 销毁item
            mAdapter.destroyItem(this, pos, ii.object);              
    }
    private static final int DEFAULT_OFFSCREEN_PAGES = 1;
    public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
                    DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

在populate()方法中:
创建ItemView:mAdapter.instantiateItem(this, position);
销毁ItemView:mAdapter.destroyItem(this, pos, ii.object);
所以由ViewPager的源码可以看出,ViewPager里边无论放多少个页面都不会内存溢出,它会不断的去创建和销毁view;

和 ListView、RecyclerView不一样,ListView、RecyclerView是会不断的复用view,而viewpager是不断的创建和销毁view

2. ViewPager加载页面的原理如图所示:

ViewPager系列文章(一)- ViewPager源码分析及加载页面原理图_第1张图片
ViePager加载页面的原理.png

轮播图刚打开默认显示当前页,是第一页,默认会缓存左右两个页面,如果左边没有,只有右边有,那么右边是第0页,当前页是第一页;
如果你滑动到第1页,ViewPager会默认把 左边第0页 和 右边第2页 创建出来;
如果你滑动到第2页,ViewPager会默认把第1页和第3页创建出来,而原来的第0页就会变成需要销毁的页面;

如果想要缓存多页,可以调用setOffscreenPageLimit()方法:
setOffscreenPageLimit(1):ViewPager机制默认就是缓存1,表示左边、右边各缓存1页,加上自己,总共是3页,其余页面全部销毁;
setOffscreenPageLimit(2):表示默认给左右各缓存2页,共4页,加上自己,总共缓存5页,其余页面全部销毁;
setOffscreenPageLimit(3):表示默认给左右各缓存3页,共6页,加上自己,总共缓存7页,其余页面全部销毁;

3. 总结:

1>:ViewPager真正的子View只是两边 "缓存" 的页面+1(当前显示页面),那么ViewPager如何做到从头滑动到尾不出问题呢?

因为 smoothScrollTo()滑动方法也调用populate(),而populate()方法维护了当前显示页面和 左右缓存的页面,就能做到无限滑动而不出问题;

2>:populate()如何让 ViewPager的子View 一直保持为 两边"缓存"页面 + 当前页面?

A:从populate()源码中可知:先判断页面是否在缓存范围内:如果在,则addNewItem添加进来,否则在destroyItem掉;
B:ViewPager会缓存左右两边页面+1(当前显示页面),默认认为当前页面的 左右两边各有1个,用户可以手动调用setOffscreenPageLimit()方法设置数量,如果传的值小于1,就默认设置为1;
ViewPager实际示意图如下:


ViewPager系列文章(一)- ViewPager源码分析及加载页面原理图_第2张图片
ViewPager实际示意图.png

你可能感兴趣的:(ViewPager系列文章(一)- ViewPager源码分析及加载页面原理图)