共计 2194 个字符,预计需要花费 6 分钟才能阅读完成。
前言
本文会从头开始一步一步带你去写一个 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 的数据,比方
能够看见切换都是失常的
最初
明天的文章就到这里,感谢您的浏览,有问题能够在评论区留言探讨,期待与大家共同进步。喜爱的话不要忘了三连。大家的反对和认可,是我分享的最大能源。