viewpager禁止预加载

作者: weiyushuai | 来源:发表于2017-09-04 11:59 被阅读1038次

    项目开发中需要fragment传递数据到activity中,由于fragment是配合viewpager的,而viewpager会自动预加载上一页和下一页,导致传递到activity的数据是错乱的,然后就想到不让viewpager预加载,viewpager有一个方法viewpager.setOffscreenPageLimit(0);表示你要加载几页,添加了此方法后发现并没有什么卵用.....

    • 网上大多数说法是懒加载,即让ViewPager预加载初始化UI,而具体一些数据,网络访问请求等延迟加载。这是靠Fragment里有一个setUserVisibleHint(boolean isVisibleToUser)的方法,我们可以在这个方法里做判断,当其True可见时(即切换到某一个具体Fragment)时才去加载数据,这样可以省流量。但这里并不满足我的需求,因为某一个Fragment并不会在ViewPager滑动到其相邻的Fragment时销毁。这个只可以解决部分人问题。

    我们需要了解下ViewPager的预加载机制

    public class ViewPager extends ViewGroup {
        private static final String TAG = "ViewPager";
        private static final boolean DEBUG = false;
    
        private static final boolean USE_CACHE = false;
    
        private static final int DEFAULT_OFFSCREEN_PAGES = 1;
        private static final int MAX_SETTLE_DURATION = 600; // ms
        private static final int MIN_DISTANCE_FOR_FLING = 25; // dips
    
        private static final int DEFAULT_GUTTER_SIZE = 16; // dips
    
        private static final int MIN_FLING_VELOCITY = 400; // dips
    
        static final int[] LAYOUT_ATTRS = new int[] {
            android.R.attr.layout_gravity
        };
    
    

    上面是viewpager源码 DEFAULT_OFFSCREEN_PAGES 这个变量表示默认加载几页

    • 上文中我想给setOffscreenPageLimit(0)设置为0不进行预加载,为什么会没用呢?请看源码..
      * <p>You should keep this limit low, especially if your pages have complex layouts.
         * This setting defaults to 1.</p>
         *
         * @param limit How many pages will be kept offscreen in an idle state.
         */
        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();
            }
        }
    

    我们可以看到,如果你调用该方法传进来的值小于1是无效的,会被强行的拽回1。而且DEFAULT_OFFSCREEN_PAGES 这个值是private的,子类继承ViewPager也是不可见的。

    网上有第二种说法,自定义一个ViewPager,把原生ViewPager全拷过来,修改这个DEFAULT_OFFSCREEN_PAGES 值为0。这种方案没用。为什么呢?接下来就是本文的重点了。
    因为现在都8.0了,版本都老高了,其实虽然每个版本都有v4包,但是这些v4包是有差异的。这就造成高版本v4包里的ViewPager,即使你Copy它,将其DEFAULT_OFFSCREEN_PAGES的值改为0,还是不起作用的,其中的逻辑变了。具体哪里变了导致无效我也没有继续研究了。

    • 完美解决方案:所以关于禁止ViewPager预加载的完美解决方案就是,使用低版本v4包里的ViewPager,完全copy一份,将其中的DEFAULT_OFFSCREEN_PAGES值改为0即可。亲测 API 14 即 Android 4.0的v4包里ViewPager 有效。

    直接上代码:

      此处省略5000字.....
    

    由于代码太长,下篇文章上代码

    相关文章

      网友评论

        本文标题: viewpager禁止预加载

        本文链接:https://www.haomeiwen.com/subject/edtejxtx.html