很多情况下,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 交互的FragmentPagerAdapterFragmentStatePagerAdapter 被弃用了」

至此我们捋顺了 setMaxLifecycle 的出现,setUserVisibleHint 的弃用以及与ViewPager 相关的 FragmentPagerAdapterFragmentStatePagerAdapter 的弃用

setMaxLifecycle 内部逻辑

接下来我们看看 setMaxLifecycle 是如何发挥作用的

首先我们要研究一下 fragment 的状态管理,为了更好的管理 fragment 的状态,官方添加了 FragmentStateManager 类来专门管理 fragment 的状态,职能单一原则哈

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

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

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

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

至此,我们理清了 setMaxLifecycle() 的内部逻辑

我们可以看到官方为了使 fragment 能够在正确的生命周期上,引入了 setMaxLifecycle() 方法,同时为了更好的管理 fragment 的状态,抽象出了 FragmentStateManager 。更少的代码,更少的职责,fragment 的内部逻辑会越来越清晰

  • 关于如何迁移至 ViewPager2 ,请移步 官方视频

  • 关于新的 API 下懒加载实现,请移步 Androidx 下 Fragment 懒加载的新实现

我是 Fly_with24

  • 掘金

  • 简书

  • Github

欢迎关注我的公众号

很多情况下,fragment 的生命周期上限应该低于 FragmentManager/Activity。例如,ViewPager 屏幕外的界面不应被 resumed理想状态下,可以通过以...
Android应用开发过程中,ViewPager同时加载多个fragment,以实现多tab页面快速切换, 但是fragment初始化时若加载的内容较多,就可能导致整个应用启动速度缓慢,影响用户体验。 为了提高用户体验,我们会使用一些懒加载方案,实现加载延迟。这时我们会用到getUserVisibleHint()与setUserVisibleHint()这两个方法 在传统的frag
大家开发Android的APP的时候,应该都是用过FragmentFragment使用起来非常方便,灵活。在ViewPage中PageAdapter来管理所有的Fragment即可。 但是大家都会遇到一个问题,就是在加载一个Fragment的时候,会自动缓存左右几个(默认是一个)页面,此时也会调用到正常的生命周期函数,onCreate,onCrateView,onResume.可是这样给用户
问题:fragmentsetUserVisibleHint不执行 在实现fragment的懒加载时发现setUserVisibleHint不执行,查阅资料才发现,setUserVisibleHint只有结合FragmentPagerAdapter才能使用。 Integer::parseInt Integer类的方法:public static int parseInt(String s) 将此String转换为int类型数据 定义一个接口(Converter),里面定义一个抽象方法 int convert(String s); 定义一个测试类(ConverterDemo),在测试类中提供两个方法 一个方法是
activity_main viewpager+fragment+侧滑的切换布局 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http:/
为什么使用setMaxLifecycle setUserVisibleHint方式已经不推荐使用了,替代它的方案就是setMaxLifecycle,这里不再具体讲解setMaxLifecycle(讲我也不会哈哈) 推荐一篇文章:setMaxLifecycle讲解,想具体了解可以看看。 实现fragment懒加载: FragmentPagerAdapter适配器构造方...
在viewpager + fragment 联合使用时,利用setUserVisibleHint进行懒加载时,发现并不适用于view的操作。。。因为setUserVisibleHint是早于oncreateview之前执行的,所以会报空指针,用一段代码演示一下 @Override public void setUserVisibleHint(boolean isVisible
原因(fragment+TabLayout+ViewPager): 使用了这个:BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 而不是说这个:BEHAVIOR_SET_USER_VISIBLE_HINT 使用这个:BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT的源码追踪: