ViewPager取消预加载

本文介绍如何在Android的ViewPager中实现懒加载,通过自定义Fragment基类并使用setUserVisibleHint方法来判断Fragment是否可见,从而控制数据加载。适用于FragmentPagerAdapter及FragmentStatePagerAdapter。

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

ViewPager默认的情况是要进行预加载的,这么做是为了保证滑动的流畅性。但有时候我们需要在滑动到该页面的时候再进行加载,网上有好多人说利用

ViewPager.setOffscreenPageLimit(int limit)

然而这个方法并不起作用

正确的方法应该是利用两个方法 void setUserVisibleHint(boolean isVisibleToUser)、boolean getUserVisibleHint()来判断当前的fragment是否可见。

经过测试 setUserVisibleHint(boolean isVisibleToUser)方会在在 onCreate() 调用后,onCreateView()调用前执行。

在此构建一个通用 fragment,并设置boolean类型的isVisible来判断 fragment 是否可见。

import android.support.v4.app.ListFragment;

public abstract class LazyListFragment extends ListFragment {
    // 当前可见标识
    protected boolean isVisible;  

    /** 
     * 在这里实现Fragment数据的缓加载
     * @param isVisibleToUser 
     */  
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(getUserVisibleHint()) {  
            isVisible = true;  
            onVisible();  
        } else {  
            isVisible = false;  
            onInvisible();  
        }
    }
  
    protected void onVisible(){  
        lazyLoad();  
    }
    
    /**
     *
     * 当前可见时执行的函数
     */
    protected abstract void lazyLoad(); 
  
    protected void onInvisible(){
    	
    }
}

让 ViewPager 里面的fragment都继承 LazyListFragment,我写了两个 fragment(分别起名为“娱乐”和“体育”),执行后查看 log 信息如下:


可以看到 ViewPager 默认启动了两个 fragment,但是只有当前可见的“娱乐” fragment 调用了 setUserVisibleHint() 方法,并设置当前可见状态为 true


还有一些童鞋可能测试后发现 fragment 没有调用setUserVisibleHint(),这是因为该方法只适用于继承了FragmentPagerAdapter 的Adapter,而继承了 FragmentStatePagerAdapter 的Adapter不会调用 fragment 的setUserVisibleHint(),具体原因还有待查实,如有大神知道,还请不吝赐教。



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

最近学习到一个新的适配方法,适用于FragmentPagerAdapter以及FragmentStatePagerAdapter,代码如下:

/**
 * Created by lzn on 2016/7/13.
 */
public abstract class BasePageFragment extends ListFragment {

    protected boolean isViewInitiated;
    protected boolean isVisibleToUser;
    protected boolean isDataInitiated;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isViewInitiated = true;
        prepareFetchData();
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        this.isVisibleToUser = isVisibleToUser;
        prepareFetchData();
    }

    public abstract void fetchData();

    public boolean prepareFetchData() {
        return prepareFetchData(false);
    }

    private boolean prepareFetchData(boolean forceUpdate) {
        if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
            fetchData();
            isDataInitiated = true;
            return true;
        }
        return false;
    }
}

ViewPager 里的 ListFragment 可以继承这个基类,重写 fetchData() 即可。关于上面的一种方法为何在FragmentStatePagerAdapter 中失效,等有空我再查实吧!当然如果有小伙伴知道,还请留言学习。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值