ViewPager的缓存机制和懒加载实现

在开发的时候经常使用ViewPager + Fragment ,但是你真的了解他是怎么执行的吗,是时候进行一下总结了。

1,ViewPager的适配器

FragementPagerAdapter和FragmentStatePagerAdapter

  • FragmentPagerAdapter中,即使fragment不可见了,他的事他实例还是存在于内存中,当 fragment比较多的时候,会占用较大的内存.
  • FragmentStatePagerAdapter,当fragment不可见时,可能会将fragment的实例会销毁,所以内存占会小一些
2,ViewPager 的缓存机制
    1. ViwePager 的缓存机制会默认缓存旁边的页面,是为了让页面更加流畅.在缓存旁边页面的时候会执行到onCreateView方法,如果你两个碎片的onCreateView 中都有执行请求数据的时候,旁边的页面也会发送请求,这样就会造成网络请求的一些问题。
  • 使用setOffscreenPagerLimit方法可以设置缓存页面的个数,默认为1,就算你传入负数他还是默认缓存旁边页面,也就是1
  • 由于ViewPager的默认缓存是1,所以ViewPager中至少会预加载一个页面的数据。如果页面有请求数据或者下载数据的时候,这就会影响当前显示的页面。
  • 我们知道在碎片中 只有在onCreateView方法中才可以拿到View 然后加载控件进行一些数据的设置.但是当碎片在ViewPager中的时候,缓存机制会导致旁边的页面中的onCreateView方法执行,这就是我们不想看到的结果。
  • Fragment里面有一个方法 setUserVisibleHint(boolean isVisibleToUser)方法,这个方法可以判断当前页面是否对用户可见。
  • 还有一点,当ViewPager缓存了旁边的那个碎片之后,那个碎片执行onCreateView之后,他碎片的生命周期会失效。当他被缓存抛弃的时候这个碎片就会被销毁。直到他又一次被缓存或者当他可见的时候才会执行onCreateView方法。

3,懒加载实现


定义所有碎片的基类,也就是让所有碎片继承这个类,他是一个抽象类

public abstract class FragmentFactory extends Fragment {

    private boolean isViewInitFinished;
//当Fragment所在的Activity被启动完成后回调该方法
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isViewInitFinished = true;
    }

// 当前页面是否可见
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser && isViewInitFinished){
            getData();
        }
    }
    public abstract void getData();
}
  • 让ViewPager里面要显示的碎片继承这个类并实现他的方法,在这个方法里面就可以去执行你的逻辑了。记住当实现懒加载的时候就不要在onCreateView方法执行逻辑了。当碎片加载的时候会调用父类的setUserVisibleHint方法。后判断是否是当前页面,如果是就可以在重新父类的方法中进行操作了。
  • SetUserVisibleHint方法是执行在最前面的,他会在ViewPager里面Fragment生命周期还没执行的时候调用.
  • 请注意SetUserVisibleHint方法调用的次数,在刚开始的时候会根据你设置的ViewPager的缓存个数去调用SetUserVisibleHint方法,然后Fragment显示后会在调用一次SetUserVisibleHint方法。也就是说在Fragment生命周期之前ViewPager会根据缓存个数去调用SetUserVisibleHint方法。当调用完成后,Fragment的生命周期会开始,这个时候Viewpager就会再次调用SetUserVisibleHint方法判断当前的fragment是否被显示。所以在SetUserVisibleHint中判断是否是当前页面的时候 都要判断一下 在onActivityCreated中的布尔变量是否为真,必须在这个布尔为真的时候才可以去判断当前Fragment有没有显示。

这种懒加载在官方文档中给出了明确的说明
/**
 * Created by hjm on 2017/4/13 15:40.
 */

public abstract class BaseFragment extends Fragment {

    private boolean isViewInitFinished;

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        isViewInitFinished = true;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        requestData(isVisibleToUser);
    }

    public void requestData(boolean isVisibleToUser){
        if(isViewInitFinished && isVisibleToUser){
            getData();
        }
    }

    /**
     *  this moment the fragment is visiable to user, so request data
##### #### #### #### #### **     */**
    public abstract void getData();
}

本人也是新手,如有错误请指出,谢谢!

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Android低版本中使用RecyclerView实现分页加载和懒加载机制,可以参考以下步骤: 1. 首先,需要在RecyclerView的Adapter中实现一个回调接口,用于监听RecyclerView的滚动状态。 ```java public interface OnLoadMoreListener { void onLoadMore(); } ``` 2. 在Activity或Fragment中,需要为RecyclerView添加滚动监听器,并在滚动时判断是否需要加载更多数据。当滚动到底部时,调用回调接口中的onLoadMore()方法。 ```java recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); int totalItemCount = layoutManager.getItemCount(); int lastVisibleItem = layoutManager.findLastVisibleItemPosition(); if (!isLoading && totalItemCount <= (lastVisibleItem + VISIBLE_THRESHOLD)) { if (onLoadMoreListener != null) { onLoadMoreListener.onLoadMore(); } isLoading = true; } } }); ``` 其中,VISIBLE_THRESHOLD是一个常量,用于控制滑动到底部多少个位置时开始加载更多数据。 3. 在Adapter中,需要为RecyclerView的每个Item添加一个标记,用于判断是否需要加载数据。当标记为true时,说明需要加载数据,否则不需要。 ```java private boolean isLoadingMore = false; public void setIsLoadingMore(boolean isLoadingMore) { this.isLoadingMore = isLoadingMore; notifyDataSetChanged(); } @Override public int getItemViewType(int position) { if (position == getItemCount() - 1 && isLoadingMore) { return VIEW_TYPE_LOADING; } else { return VIEW_TYPE_ITEM; } } ``` 4. 当需要加载更多数据时,需要在Activity或Fragment中调用Adapter的setIsLoadingMore()方法,将标记设置为true,并在onLoadMore()方法中加载更多数据。 ```java adapter.setIsLoadingMore(true); // 加载更多数据 ``` 5. 懒加载机制可以通过在Activity或Fragment中使用ViewPager结合Fragment实现。在ViewPager的OnPageChangeListener中,可以判断当前Fragment是否为最后一个Fragment,如果是,则开始加载数据。 ```java viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { if (position == adapter.getCount() - 1) { // 加载数据 } } @Override public void onPageScrollStateChanged(int state) { } }); ``` 需要注意的是,以上代码只是一种实现方式,具体实现方式可能会因项目需求和开发经验等因素而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tʀᴜsᴛ³⁴⁵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值