Fragment懒加载分析使用
来源:互联网 发布:淘宝pid怎么看 编辑:程序博客网 时间:2024/06/06 03:41
使用过ViewPager + Fragment的朋友都知道,ViewPager默认会管理前后一个Fragment,想要管理多个可以通过setOffscreenPageLimit这个方法来设置,也只有设置>1才起效果,请看源码:
先来看看普通的ViewPager + Fragment,也就是setOffscreenPageLimit(1)使用:
为了方便打印Log查看,这里新建三个Fragment,分别是FirstFragment、SecondFragment、ThirdFragment,都是继承了v4包的Fragment,ViewPager使用FragmentPagerAdapter。
从打印的结果可以发现有两个很严重的问题:
- ViewPager只管理前后一个Fragment,当滑到ThirdFragment,FirstFragment就会调用onDestroyView,来回切换就会导致Fragment不断在销毁重建view。
- 由于Fragment不断调用onDestroyView和onCreateView,所以会不断的在请求网络调用接口。
解决办法也很简单,想要三个Fragment都不会销毁,只需要设置setOffscreenPageLimit为2就可以了,表示管理前后两个Fragment,所以Fragment不会执行onDestoryView,接口也就不会不断调用了。
看一下设置后的结果:
从打印结果可以看到切换Fragment的确不会执行onDestoryView了,不过细心的朋友可以发现还存在个问题:
- 初始化的时候,三个Fragment都调用了onCreateView
这意味着显示FirstFragment的时候其他两个Fragment都会请求网络调用接口,很显然还没有达到想要的结果,理想的效果是显示的时候才请求网络调用接口,请求接口后切换就无需再次请求。
其实前面的Log打印图已经暴露了,没错,我们就是要利用setUserVisibleHint这个方法来处理,这个方法有个参数isVisibleToUser代表此Fragment是否可见,单凭这个当然不行,我们需要三个参数:
- isViewInit:代表View是否加载完成,在onCreateView方法赋值。
- isVisible:代表Fragment是否可见,在setUserVisibleHint方法赋值。
- isFirstLoad:代表是否第一次加载,接口调用后赋值为false。
why are you bb so much,show me the code!
public abstract class LazyFragment extends Fragment { private boolean isViewInit = false; // View是否加载完成 private boolean isVisible = false; // Fragment是否可见 private boolean isFirstLoad = true; // 是否第一次加载 @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(getLayoutId(), container, false); isViewInit = true; return view; } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); isVisible = isVisibleToUser; preLoadData(); } private void preLoadData() { if (isViewInit && isVisible && isFirstLoad) { loadData(); isFirstLoad = false; } } /** * Fragment布局ID */ protected abstract int getLayoutId(); /** * 数据处理 */ protected void loadData() { }}
看起来貌似没问题,先看结果吧。
What the fuck?为什么FirstFragment loadData方法第一次不执行?
这是前面的分析图,FirstFragment第一次不执行loadData方法是因为setUserVisibleHint先于onCreateView执行,preLoadData只在setUserVisibleHint方法有执行,执行的时候isViewInit为false,所以FirstFragment 不执行loadData方法。
那么解决就很简单了,只需要在onCreateView也执行preLoadData就可以了。有朋友可能会有疑问,那么loadData不就执行两次了?当然不会了,我们可是有三个boolean判断的呢。
来看一下修改后的结果图:
看到这里,你是否和我一样,嘴角一仰?
国际惯例,Github地址戳我
完成了,收工(⊜‿⊜)
- Fragment懒加载分析使用
- Android之Fragment懒加载分析
- fragment懒加载时生命周期分析
- Fragment的Adapter分析及懒加载
- Fragment加载过程分析。
- Fragment加载过程分析
- ViewPager+Fragment 常使用懒加载
- 使用Fragment懒加载的一种方式
- 是时候使用Fragment懒加载了
- 使用ViewPager加载Fragment
- 使用viewpage加载fragment
- 多个Fragment时的加载优化,使用懒加载
- Fragment懒加载的实现方法(含源码分析)
- android viewpager使用Fragment懒加载,滑到当前fragment才进行数据加载
- Fragment的使用分析
- ViewPager加载Fragment懒加载
- Fragment中的懒加载
- Fragment懒加载
- 测试
- 02-线性结构2 一元多项式的乘法与加法运算 (20分)
- CodeForces 598D Igor In the Museum【dfs】
- [kuangbin带你飞]专题十二 基础DP1 N POJ 2533
- CF 343D D. Water Tree(树链剖分,简单题)
- Fragment懒加载分析使用
- 基于node服务器的大文件(G级)上传
- yii2.0设置默认控制器
- 数据结构示例之十进制转换其他进制
- angularjs中ng-include使用被注释或者报错解决方法
- LeetCode[6] ZigZag Conversion(java)
- PHP+Mysql+Sphinx高效的站内搜索引擎搭建详释
- 《大话数据结构》
- centos 开启mysql 3306