前言
本文会从头开始一步一步带你去写一个LazyFragment,依据写的过程中一步一步记录,你也能够本人试一试,跟着一起写写。最初也依据遇到的问题去欠缺了,网上搜的都是不欠缺的,还是本人写一个吧!
懒加载是在加载啥?
这个问题显得很愚昧。然而想一下,懒加载到底是加载数据和视图
,还是数据
呢??(一开始我也想过这个问题。。。)当然是数据
啦,你怎么能阻止视图的加载呢!你是无奈阻止Fragment的生命周期函数的执行的,所以只能让以后显示的Fragment加载数据,不显示不加载数据
怎么能晓得以后页面是显示的这个Fragment呢?
在源码中有两个办法能够应用
在viewpager和fragment模式应用的 public void setUserVisibleHint(boolean isVisibleToUser) {}
和
在add+show+hide模式应用 public void onHiddenChanged(boolean hidden) {}
那么就先简略的试试看这两个办法好了 我写了一个Viewpager+Fragment模式的,缓存数量offscreenPageLimit为1
。
当关上app时
咱们能够看到主页BadHomeFragment
的setUserVisibleHint()办法
执行了两次
!先返回false不可见,再返回true可见。而且不论在哪个Fragment中setUserVisibleHint()
都跑得比生命周期快
当切换到第二个Fragment
切回去主页Fragment
当曾经跑过生命流程的Fragment再次显示时,只会走setUserVisibleHint()
(先疏忽onHiddenChange办法)
这样的话,咱们大略能够想到,我依据setUserVisibleHint()的可见状态
去加载数据不就完事了吗?
所以咱们先这样写
在子Fragment中的loadData中调用接口获取数据,而后给控件赋值
后果就是!报错!!说你的控件为null,我都可见了为啥为null呢。因为在进入app时setUserVisibleHint
在生命周期后面,Fragment都没有加载布局,当然为null啦
那我加个变量判断一下布局有没有加载好不就行了?
后果呢?主页Fragment没有执行onLoadData
办法,点击TwoFragment
却执行了,为什么呢,因为setUserVisibleHint
更早啊,而TwoFragment
曾经初始化过了,点击过来的时候能力失常加载数据。
所以咱们必须在生命周期中再散发一次加载数据的事件,把加载数据提成一个办法
再来看看从开启app到点击到第三个Fragment的日志,大家都失常的加载了数据,如同还挺失常的
那再试试从第一个页面跳转到最初一个页面吧,会发现两头有些页面莫名的就调用了StopLoadData
函数???这显然有问题的,看来不能只是简略的用可见状态来散发了
咱们在好好想一下,LoadData
是Fragment可见的时候调用, StopLoadData
是Fragment不可见的时候调用。其实这样说并不齐全,应该是从不可见状态到可见状态的时候
加载数据,可见状态到不可见状态的时候
进行。所以咱们得用一个变量记录一下可见状态
能够看到在切换方面,散发的事件曾经是失常的了 留神要在onStop
把`currentVisibleStatus状态重置!
以上就是咱们网上常见的懒加载了,然而会有两个问题
在跳转到其余页面回来时,会怎么样?
并不会怎么,只是回来的时候不会去散发加载数据的事件而已啧 所以我加上这样一段代码,用一个变量去判断,不须要能够不写,然而我想想你跳转了别的页面,回来数据Fragment数据应该会变,所以散发一下
在子Fragment中又有一个viewpager+Fragment又会怎么样?
这里去除掉了其余log,为了看起来分明点
我给TowFragment加了一个viewpager,外面有TowFragment1和2
进入App能够看到,爹都还没显示,儿子先加载了数据?
而且在之后的切换底部Tab,TowFragment外面的两个儿子都金石为开,只有刚关上App时加载了,连进行加载的办法都没调用到,基本就没有事件散发到儿子那里去
所以咱们必须要再做一些依据父亲和儿子的状态再做一些判断 先解决第一个问题,父Fragment还没显示,子Fragment就加载了数据。这个问题很简略,咱们只须要在散发加载数据的事件时,判断一下是否有父Fragment,且是否可见。
就能够了
依据Fragment源码中的这个办法,能够解决下面的问题
比方,父Fragment不可见时间接退出办法,不准散发
然而还有一个问题存在,就是不管怎么切换,子Fragment都不会散发加载或进行加载数据的事件。这是为啥??
从一开始咱们能够看到,在进入HomeFragment时,子Fragment也会别离调用两次setUserVisibleHint办法
,在进入前就把本人的可见状态置为true。到底前面的散发事件有效了。
所以我决定在进入他的父Fragment时,再去调用一次散发事件,真正的加载子Fragment的数据,比方
能够看见切换都是失常的
最初
明天的文章就到这里,感谢您的浏览,有问题能够在评论区留言探讨,期待与大家共同进步。喜爱的话不要忘了三连。大家的反对和认可,是我分享的最大能源。