关于ViewPager中Fragment的延时加载问题

本文探讨了在ViewPager中如何实现Fragment的延时加载,即在切换时加载数据,不在显示时预加载。分析了ViewPager的预加载机制,指出预加载范围由mOffscreenPageLimit决定,并讨论了两种实现延时加载的方法:一是修改ViewPager源码,二是利用Fragment的setUserVisibleHint()方法进行懒加载实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题背景:有的场景,Viewpager在每次切换Pager的时候去请求网络数据,刷新页面,同时在不显示的时候,又不会提前去请求数据。这就涉及到了Viewpager的预加载问题。

首先分析ViewPager预加载的原因

查看ViewPager的源码,发现第三行就定义了一个DEFAULT_OFFSCREEN_PAGES的变量,同时又将这个变量赋值给了mOffscreenPageLimit的变量。从变量的命名上,可以看出就是预加载的范围。接着通过查找可以发现,ViewPager设置预加载范围的方法。


源码展示如下:

private static final int DEFAULT_OFFSCREEN_PAGES = 1;
private int mOffscreenPageLimit = DEFAULT_OFFSCREEN_PAGES;

从代码的注释来看,可以看出,这个方法就是用来规定,预加载的范围的,但是,代码中也写明了。最小范围是1,也就是左右范围1页。

/**
     * Set the number of pages that should be retained to either side of the
     * current page in the view hierarchy in an idle state. Pages beyond this
     * limit will be recreated from the adapter when needed.
     *
     * <p>This is offered as an optimization. If you know in advance the number
     * of pages you will need to support or have lazy-loading mechanisms in place
     * on your pages, tweaking this setting can have benefits in perceived smoothness
     * of paging animations and interaction. If you have a small number of pages (3-4)
     * that you can keep active all at once, less time will be spent in layout for
     * newly created view subtrees as the user pages back and forth.</p>
     *
     * <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();
        }
    }


分析完预加载的原因,现在我们分析,如果做到,只加载当前显示页,不加载预加载的页面呢?

第一个方法,因为上述两个边路都是私有,所以使用继承好像不能解决问题,就只能完全复制ViewPager的代码来实现了。工程量有点大啊。


第二个方法,我们发现Fragment有一个方法是 setUserVisibleHint()方法,这个方法在OnCreateView方法之前调用,并且每次Fragement显示与不显示的时候都会调用

所以讲需要请求数据的接口从之前别的回调函数中转移到次方法中即可。这样也可以变相的实现Lazy Load功能

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        // TODO Auto-generated method stub
        super.setUserVisibleHint(isVisibleToUser);
        if(isVisibleToUser){
            getValues();
        }
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值