ViewPager+TabLayout+Fragment懒加载机制完全解析
2017-08-22 15:10
441 查看
ViewPager+TabLayout+Fragment懒加载机制完全解析
作者 Ruheng 关注
2017.03.03 10:52* 字数 1046 阅读 1905评论
13喜欢 74
在Fragment和ViewPager配合使用的时候,ViewPager会使用预加载机制,使得我们在没有跳转到对应页面时,可能已经加载好了,这是个非常不好的用户体验,浪费用户的流量。本篇文章主要讲解在ViewPager+TabLayout+Fragment的情况下,Fragment的懒加载机制的实现以及项目封装情况。
一、setUserVisibleHint(boolean isVisibleToUser)
setUserVisibleHint(boolean isVisibleToUser)是Fragment中的一个回调函数。当前Fragment可见时,setUserVisibleHint()回调,其中isVisibleToUser=true。当前Fragment由可见到不可见或实例化时,setUserVisibleHint()回调,其中isVisibleToUser=false。setUserVisibleHint(boolean isVisibleToUser)调用时机
①在Fragment实例化,即在ViewPager中,由于ViewPager默认会预加载左右两个页面。
4000
此时预加载页面回调的生命周期流程:setUserVisibleHint() -->onAttach() --> onCreate()-->onCreateView()--> onActivityCreate() --> onStart() --> onResume()
此时,setUserVisibleHint() 中的参数为false,因为不可见。
②在Fragmetn可见时,即ViewPager中滑动到当前页面时,因为已经预加载过了,之前生命周期已经走到onResume() ,所以现在只会回调:setUserVisibleHint() 。
此时,setUserVisibleHint() 中的参数为true,因为可见。
③在Fragment由可见变为不可见,即ViewPager由当前页面滑动到另一个页面,因为还要保持当前页面的预加载过程,所以只会回调:setUserVisibleHint()。
此时,setUserVisibleHint() 中的参数为false,因为不可见。
④由TabLayout直接跳转到一个未预加载的页面,此时生命周期的回调过程:setUserVisibleHint() -->setUserVisibleHint() -->onAttach() --> onCreate()-->onCreateView()--> onActivityCreate() --> onStart()
--> onResume()
回调了两次setUserVisibleHint() ,一次代表初始化时,传入参数是false,一次代表可见时,传入参数是true。这种情况比较特殊。
总结:无论何时,setUserVisibleHint()都是先于其他生命周期的调用,并且初始化时调用,可见时调用,由可见转换成不可见时调用,一共三次时机。
二、封装实现懒加载机制
加载网络的情况:①setUserVisibleHint()中参数为true,即Fragment可见;
②onCreateView()方法调用完毕,返回rootView,防止造成空指针问题;
③第一次调用网络加载,之前没加载过,即isFirst = false(有些别扭,可以改成true,对应代码做下修改)。
满足以上条件,加载网络请求。
取消加载网络的情况:
①setUserVisibleHint()中参数由true变为false,即Fragment由可见变为不可见;
②不是第一次调用网络加载,之前加载过,即isFirst = true。
满足以上两者条件(只满足第一点也可以),取消网络请求。
封装代码
在BaseFragment中进行封装其中isFragment表示当前Fragment的可见情况
isFirst表示是否已经加载过
onFragmentVisibleChange()是一个可继承的空方法,子类实现,传入true,代表加载网络,传入false,代表取消网络加载。
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { isFragmentVisible = true; } if (rootView == null) { return; } //可见,并且没有加载过 if (!isFirst&&isFragmentVisible) { onFragmentVisibleChange(true); return; } //由可见——>不可见 已经加载过 if (isFragmentVisible) { onFragmentVisibleChange(false); isFragmentVisible = false; } }
protected void onFragmentVisibleChange(boolean isVisible) { }
其中有一种特殊情况不能满足上述代码中的条件进行网络加载。
特殊情况:当TabLayout跳转到一个没有预加载过的Fragment,连续调用两次setUserVisibleHint方法,但此时rootView为空,不能进行加载。需要在onCreateView()方法最后判断是否进行网络加载,然后调用onFragmentVisibleChange(true)方法
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ................. //可见,但是并没有加载过 if (isFragmentVisible && !isFirst) { onFragmentVisibleChange(true); } return rootView; }
子类实现的实例:
@Override protected void onFragmentVisibleChange(boolean isVisible) { if(isVisible){ //可见,并且是第一次加载 mPresenter.requestPhotoList(SIZE,mStartPage); LoadingDialog.showDialogForLoading(getActivity()); }else{ //取消加载 RxDisposeManager.get().cancel("photoList"); LoadingDialog.cancelDialogForLoading(); } }
三、效果实现
上图效果可以看出实现了懒加载,并且再次滑动回对应Fragment,也不会加载,通过下拉刷新才能更新数据,减少流量的耗费。
上图效果可以看出,当TabLayout直接跳转到没有预加载的页面,也可以实现懒加载,效果一样。
小伙伴们有没有很心动,下面有源码,欢迎参考使用!
源码地址
只需要看BaseFragment部分即可
相关文章推荐
- ViewPager+TabLayout+Fragment懒加载机制完全解析
- TabLayout +ViewPager+Fragment + RecycleView + webView加载本地html
- TabLayout ViewPager Fragment 实现底部按钮菜单 Fragment 实现懒加载
- 仿 今日头条布局:TabLayout+ViewPager+Fragment+ListView多条目加载+Webview
- 项目解析一:仿csdn 代码解析(TabLayout,Viewpager,FragmentPagerAdapter)
- 网络判断+xlistview上拉加载、下拉刷新+Tablayout +图片拖拽缩放+数据库存储 3、案例完成思路要求: 模块一:用fragment+viewpager+Tablayout实现页面
- Android开发ViewPager的预加载和Fragment的销毁问题,以及tabLayout+ViewPager的使用,tablayout平板适配问题解决
- TabLayout +ViewPager+Fragment + RecycleView + webView加载本地html
- TabLayout+ViewPager+Fragment懒加载实现
- Tablayout+viewpager+Fragment的数据加载问题
- 解决TabLayout +ViewPager + Fragment 不让预加载的问题
- TabLayout +ViewPager+Fragment + RecycleView + webVie 4000 w加载本地html
- 巧力避免ViewPager的预加载数据,Tablayout+Fragment+viewPager
- tablayout+viewpager+fragment懒加载
- TabLayout+ViewPager+Fragment(懒加载)实现导航栏
- Android应用ViewPager和TabLayout动态加载Fragment,并实现view和tab动态刷新。
- [置顶] 巧力避免ViewPager的预加载数据,Tablayout+Fragment+viewPager
- TabLayout+ViewPager+Fragment实现懒加载
- TabLayout+ViewPager+fragment实现懒加载
- Android开发之漫漫长途 Fragment番外篇——TabLayout+ViewPager+Fragment