}
复杂 Fragment 嵌套的情况
当然,在实际项目中,我们可能会遇到更为复杂的 Fragment 嵌套组合。比如 Fragment+Fragment、Fragment+ViewPager、ViewPager+ViewPager….等等。
如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZW7l48kv-1651211677559)(//upload-images.jianshu.io/upload_images/2824145-f7f0a97b856f52b2.jpg?imageMogr2/auto-orient/strip|imageView2/2/w/984/format/webp)]
对于以上场景,我们就需要重写我们的懒加载,以支持不同嵌套组合模式下 Fragment 正确懒加载。我们需要将 LazyFragment 修改成如下这样:
abstract class LazyFragment : Fragment() {
/**
- 是否执行懒加载
*/
private var isLoaded = false
/**
- 当前Fragment是否对用户可见
*/
private var isVisibleToUser = false
/**
- 当使用ViewPager+Fragment形式会调用该方法时,setUserVisibleHint会优先Fragment生命周期函数调用,
- 所以这个时候就,会导致在setUserVisibleHint方法执行时就执行了懒加载,
- 而不是在onResume方法实际调用的时候执行懒加载。所以需要这个变量
*/
private var isCallResume = false
/**
- 是否调用了setUserVisibleHint方法。处理show+add+hide模式下,默认可见 Fragment 不调用
- onHiddenChanged 方法,进而不执行懒加载方法的问题。
*/
private var isCallUserVisibleHint = false
override fun onResume() {
super.onResume()
isCallResume = true
if (!isCallUserVisibleHint) isVisibleToUser = !isHidden
judgeLazyInit()
}
private fun judgeLazyInit() {
if (!isLoaded && isVisibleToUser && isCallResume) {
lazyInit()
Log.d(TAG, "lazyInit:!!!”)
isLoaded = true
}
}
override fun onHiddenChanged(hidden: Boolean) {
super.onHiddenChanged(hidden)
isVisibleToUser = !hidden
judgeLazyInit()
}
override fun onDestroyView() {
super.onDestroyView()
isLoaded = false
isVisibleToUser = false
isCallUserVisibleHint = false
isCallResume = false
}
override fun setUserVisibleHint(isVisi 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》无偿开源 徽信搜索公众号【编程进阶路】 bleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
this.isVisibleToUser = isVisibleToUser
isCallUserVisibleHint = true
judgeLazyInit()
}
abstract fun lazyInit()
}
Androidx 下的懒加载
虽然之前的方案就能解决轻松的解决 Fragment 的懒加载,但这套方案有一个最大的弊端,就是不可见的 Fragment 执行了 onResume() 方法
。onResume 方法设计的初衷,难道不是当前 Fragment 可以和用户进行交互吗?你他妈既不可见,又不能和用户进行交互,你执行 onResume 方法干嘛?
基于此问题,Google 在 Androidx 在 FragmentTransaction
中增加了 setMaxLifecycle
方法来控制 Fragment 所能调用的最大的生命周期函数。如下所示:
/**
- Set a ceiling for the state of an active fragment in this FragmentManager. If fragment is
- already above the received state, it will be forced do