Fragment新功能,setMaxLifecycle了解一下

前言

写上一篇ViewPager2软文时,我发现最新的Fragment代码淘汰了setUserVisibleHint方法,转而支持用setMaxLifecycle方法,setMaxLifecycle言外之意是设置最大生命周期,懂行的人应该知道,Fragment一直都是没法直接设置生命周期,必须经过addattachremovedetachshowhide方法间接干预,原本就此功能,简单介绍一下setMaxLifecycle的原理和上手效果;android

阅读指南:bash

  • 本文基于androidx 1.1.0-alpha07版本的fragment进行,也是支持setMaxLifecycle的最低版本
  • 本文会根据FragmentPagerAdapter进行setMaxLifecycle示例应用讲解

基本介绍

setMaxLifecycle定义在FragmentTransaction中,和以前的addattachremovedetachshowhide等方法是并列关系;markdown

FragmentTransactionide

public FragmentTransaction setMaxLifecycle(@NonNull Fragment fragment,
        @NonNull Lifecycle.State state) {
    addOp(new Op(OP_SET_MAX_LIFECYCLE, fragment, state));
    return this;
}
复制代码

参数解读:this

  • fragment 即须要操做的Fragment对象,前提条件是这个fragment必须已经加到FragmentManager中;
  • state Lifecycle.State枚举类型,该参数的使用条件是至少是Lifecycle.State.CREATED,不然报IllegalArgumentException异常

Lifecycle.State一共有五个状态,最低要求是Lifecycle.State.CREATED,因此该方法可用的参数有CREATEDSTARTEDRESUMEDState生命周期方法有何区别,下面简单解释一下:spa

生命周期状态理解

在Fragment中,定义了五种State,这里的State并不是上面说Lifecycle.State,可是逻辑基本上是一致的;code

  • INITIALIZING 初始状态
  • CREATED 已建立状态
  • ACTIVITY_CREATED 彻底建立,可是没有started
  • STARTED 建立并启动,可见不可操做
  • RESUMED 建立启动并可操做

本文内容只对CREATEDSTARTEDRESUMED这三个状态讲解,因为Fragment中定义的mStateLifecycle.State不是同一状态,在本文视为同一律念;orm

与生命周期对应关系

各位确定都知道Fragment生命周期有onDestoryonStop等方法,可是状态却没有这么多,那么如何标识状态和对应关系,下面给出对应关系;对象

首先,我把生命周期方法从onCreate->onCretateView->onStart->onResume->onPause->onStop-> onDestoryView->onDestory视为从小到大排序;排序

一样的,咱们把生命周期状态CREATED->STARTED->RESUMED视为从小到大排序;

  • CREATED状态

CREATED即已建立状态,狭义的理解是生命周期方法走到onCreate,若是当前fragment状态已大于CREATED,则会使fragment生命周期方法走到onDestoryView,若是小于CREATED,则走到onCreate;因此CREATED有两种状况;

  • STARTED状态

同理,STARTED状态也有两种状况,若是当前fragment状态已大于STARTED,则会使fragment生命周期方法走到onPause,若是小于CREATED,则走到onStart

  • RESUMED状态

RESUMED表示的状态比较特殊,只表明onResume状态,不管大到小仍是小到大,最终都是停留到onResume状态;

以上生命周期状态扭转结论基于FragmentManagerImpl.moveToState()方法提取,若有误导,请指教

如何使用

setMaxLifecycle能够单独使用,也能够配合add等方法组合使用,首先,咱们分析单独执行add命令的状态变化:

单独执行add操做

FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.commit();
复制代码

add配合setMaxLifecycle(Lifecycle.State.CREATED)

FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.CREATED);
fragmentTransaction.commit();
复制代码

add配合setMaxLifecycle(Lifecycle.State.STARTED)

FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.STARTED);
fragmentTransaction.commit();
复制代码

add配合setMaxLifecycle(Lifecycle.State.RESUMED)

FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.RESUMED);
fragmentTransaction.commit();
复制代码

单独使用setMaxLifecycle

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setMaxLifecycle(cardFragment, xxx);
fragmentTransaction.commit();
复制代码
  • RESUMED状态的Fragment进行操做CREATED操做

  • RESUMED状态的Fragment进行操做STARTED操做

  • RESUMED状态的Fragment进行操做CREATED操做,在进行STARTED操做

因为篇幅缘由,就不一一介绍各类组合状况,只要弄清楚生命周期状态,不管是状态是升仍是降,不论组合仍是单用,你均可以驾驭;

FragmentPagerAdapter变更

因为setMaxLifecycle带来了生命周期设置,替换掉了老旧的setUserVisibleHint方法,因此在FragmentPagerAdapter中也进行了适配

FragmentPagerAdapter

public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0;
public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1;

private final int mBehavior;

public FragmentPagerAdapter(@NonNull FragmentManager fm) {
    this(fm, BEHAVIOR_SET_USER_VISIBLE_HINT);
}

public FragmentPagerAdapter(@NonNull FragmentManager fm,@Behavior int behavior) {
    mFragmentManager = fm;
    mBehavior = behavior;
}
复制代码

最新的FragmentPagerAdapter用一个mBehavior来控制setUserVisibleHintsetMaxLifecycle二选一的局面; mBehavior在构造方法中指定;

从代码能够看出,用setMaxLifecycle(mCurrentPrimaryItem, Lifecycle.State.STARTED)替代setUserVisibleHint(false),用setMaxLifecycle(fragment, Lifecycle.State.RESUMED)替代setUserVisibleHint(true)

为何要用Lifecycle.State.STARTED?由于这里本质上用的是add+Lifecycle.State.STARTEDattach+Lifecycle.State.STARTED组合;

最终的结果是不可见的Fragment只会走到生命周期onStart方法,不会走onResume方法;

懒加载新方案

综上,过去使用setUserVisibleHint来控制Fragment懒加载,在最新版的FragmentPagerAdapter里有新思路,能够切换到BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT模式,在FragmentonResume里判断,更符合显示逻辑;

切换到BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT模式,须要调用俩参数的构造方法:

new FragmentPagerAdapter(getSupportFragmentManager(),FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
复制代码

总结

破事水了小半天,本文到底说了什么内容,仍是作个总结吧:

首先使用setMaxLifecycle能进一步的控制Fragment生命周期,一句话形容就是对addattach等命令的补充;

其次该功能在官方控件中得以运用,改善了ViewPager+Fragment的使用体验,懒加载注意点;

最后鼓励你们(主要是本身)多看源码,夯实基础,方能不变应万变,本文结束。

相关文章
相关标签/搜索