您的位置:首页 > 其它

ViewPager之setOffscreenPageLimit()解析和实现懒加载

2017-04-13 15:58 405 查看

ViewPager之setOffscreenPageLimit()解析

在开发中经常使用ViewPager+Fragment,但是你真的了解在此情景下的Fragment的生命周期吗, 使用了那么频繁, 是该好好的总结下了:

ViewPager 中两种Adapter: FragmentPagerAdapter, FragmentStatePagerAdapter 的区别

setOffscreenPageLimit 分析, Fragment 生命周期分析

在 ViewPager中 Fragment 实现懒加载的正确姿势

1.FragmentPagerAdapter, FragmentStatePagerAdapter 的区别
FragmentPagerAdapter 中, 即使fragment不可见了, 他的视图可能会 destory(执行 onViewDestory, 是否执行与setOffscreenPageLimit 方法设置的值有关), 但是他的实例仍然会存在于内存中. 当较多的fragment时, 会占用较大的内存.

FragmentSatePagerAdapter 中, 当fragment不可见时, 可能会将fragment的实例也销毁(执行 onDestory, 是否执行与setOffscreenPageLimit 方法设置的值有关). 所以内存开销会小些, 适合多fragment的情形.

2.setOffscreenPageLimit 方法分析与 Fragment生命周期分析
setOffscreenPageLimit 方法设置的默认值是1.这个设置的值有两层含义: 一是 ViewPager 会预加载几页; 二是 ViewPager 会缓存 2*n+1 页(n为设置的值).

明白了setOffscreenPageLimit 方法的含义后就明白了在 ViewPager 中Fragment的生命周期了:在 FragmentPagerAdapter 中 setOffscreenPageLimit 的值影响的是 onViewDestory 方法.当缓存的 fragment 超过 setOffscreenPageLimit 设置的值后, 那些 fragment 的onViewDestory 方法会回调; 在 FragmentStatePagerAdapter 中, 当缓存的 fragment 超过 setOffscreenPageLimit 设置的值后, 那些 fragment 的onDestory 方法会回调 .

总结起来就一句话: ViewPager 中的 fragment 是否执行 onViewDestory 或者 onDestory 与 setOffscreenPageLimit 方法设置的值有关.

3.懒加载实现思路
由于ViewPager 的setScreenPageLimit 方法默认值是 1 ,所以在 ViewPager 中至少会预加载一页. 当然了预加载页面是有好处的, 但是对于页面的数据, 那就没有必要去预加载了, 如果当前加载的页面有多个请求, 又预加载下个页面的请求, 导致多个任务等待, 这会影响到当前页面的请求速度. 所以合理的做法是当页面对于用户可见时再去请求数据.

可能有的同学会想到, 那就在 Fragment 的 onResume 去做请求数据的操作不就行了吗! 如果真是这样 easy, 那就没必要写这篇文章了~~ 因为有预加载, 下一页的 fragment 的 onStart, onResume 方法都会执行. 怎么办?

Fragment 里面有个方法 setUserVisibleHint(boolean isVisibleToUser) 方法. 这个方法可以判断当前页面是否对用户可见. 但是这个方法有点坑, 如果你直接在这个回调方法里面做请求, 那就坑你了,哈哈~~

setUserVisibleHint(boolean isVisibleToUser) 这个方法的回调不是和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();
}


nice, 完美解决!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  懒加载