很多情况下,fragment 的生命周期上限应该低于 FragmentManager/Activity。例如,ViewPager
屏幕外的界面不应被 resumed
理想状态下,可以通过以下 API 实现
supportFragmentManager.beginTransaction()
.setMaxLifecycle(fragment, Lifecycle.State.RESUMED)
.commit()
将最大生命周期设置为 Lifecycle.State.RESUMED
将有效地消除限制(因为这是最高生命周期状态)
这将允许废弃 setUserVisibleHint()
API
setMaxLifecycle 出现始末
该功能应如何实现的?我们沿着 commit log
来理一下官方的思路
将 BackStackRecord
的部分逻辑转移至父类 FragmentTransaction
中


在 FragmentTransaction
中添加 setMaxLifecycle
API


保存 fragment maxState


弃用 setUserVisibleHint

FragmentPagerAdapter
构造器新增参数,使用 setMaxLifecycle()
API 确保 fragment resumed
时对用户可见


弃用 FragmentStatePagerAdapter
原来的单参构造器,推荐使用新的构造


随着 ViewPager2 1.0.0
正式版发布,与 ViewPager
交互的FragmentPagerAdapter
和 FragmentStatePagerAdapter
被弃用了

至此我们捋顺了 setMaxLifecycle
的出现,setUserVisibleHint
的弃用以及与ViewPager
相关的 FragmentPagerAdapter
和 FragmentStatePagerAdapter
的弃用
setMaxLifecycle 内部逻辑
接下来我们看看 setMaxLifecycle
是如何发挥作用的
首先我们要研究一下 fragment 的状态管理,为了更好的管理 fragment 的状态,官方添加了 FragmentStateManager
类来专门管理 fragment 的状态,职能单一原则哈


接着在该类中添加了计算 fragment 最大生命周期的方法 computeMaxState()


后来该方法改名为 computeExpectedState()
并加入了 moveToExpectedState()
方法

computeExpectedState()
方法会根据 fragment mMaxState
计算 fragment 应该所处的生命周期

而 fragment 的 mMaxState
是通过 FragmentManager
的 setMaxLifecycle()
方法设置的 ,而该方法是 BackStackRecord
执行 OP 时调用的,而 OP 值正是通过 FragmentTransaction
的 setMaxLifecycle()
设置的


至此,我们理清了 setMaxLifecycle()
的内部逻辑
总结
我们可以看到官方为了使 fragment 能够在正确的生命周期上,引入了 setMaxLifecycle()
方法,同时为了更好的管理 fragment 的状态,抽象出了 FragmentStateManager
。更少的代码,更少的职责,fragment 的内部逻辑会越来越清晰
-
关于如何迁移至 ViewPager2 ,请移步 官方视频
-
关于新的 API 下懒加载实现,请移步 Androidx 下 Fragment 懒加载的新实现