寫上一篇ViewPager2軟文時,我發現最新的Fragment
代碼淘汰了setUserVisibleHint
方法,轉而支持用setMaxLifecycle
方法,setMaxLifecycle
言外之意是設置最大生命週期
,懂行的人應該知道,Fragment
一直都是沒法直接設置生命週期,必須經過add
、attach
、remove
、detach
、show
、hide
方法間接干預,原本就此功能,簡單介紹一下setMaxLifecycle
的原理和上手效果;android
閱讀指南:bash
androidx 1.1.0-alpha07
版本的fragment
進行,也是支持setMaxLifecycle
的最低版本FragmentPagerAdapter
進行setMaxLifecycle
示例應用講解setMaxLifecycle
定義在FragmentTransaction
中,和以前的add
、attach
、remove
、detach
、show
、hide
等方法是並列關係;ide
FragmentTransactionui
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
,因此該方法可用的參數有CREATED
、STARTED
、RESUMED
,State
和生命週期方法
有何區別,下面簡單解釋一下:spa
在Fragment中,定義了五種State
,這裏的State
並不是上面說Lifecycle.State
,可是邏輯基本上是一致的;code
INITIALIZING
初始狀態CREATED
已建立狀態ACTIVITY_CREATED
徹底建立,可是沒有startedSTARTED
建立並啓動,可見不可操做RESUMED
建立啓動並可操做
本文內容只對CREATED
、STARTED
、RESUMED
這三個狀態講解,因爲Fragment中定義的mState
和Lifecycle.State
不是同一狀態,在本文視爲同一律念;cdn
各位確定都知道Fragment生命週期有onDestory
,onStop
等方法,可是狀態卻沒有這麼多,那麼如何標識狀態和對應關係,下面給出對應關係;對象
首先,我把生命週期方法從onCreate
->onCretateView
->onStart
->onResume
->onPause
->onStop
-> onDestoryView
->onDestory
視爲從小到大排序;blog
一樣的,咱們把生命週期狀態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
操做因爲篇幅緣由,就不一一介紹各類組合狀況,只要弄清楚生命週期狀態,不管是狀態是升仍是降,不論組合仍是單用,你均可以駕馭;
因爲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
來控制setUserVisibleHint
和setMaxLifecycle
二選一的局面; mBehavior
在構造方法中指定;
從代碼能夠看出,用setMaxLifecycle(mCurrentPrimaryItem, Lifecycle.State.STARTED)
替代setUserVisibleHint(false)
,用setMaxLifecycle(fragment, Lifecycle.State.RESUMED)
替代setUserVisibleHint(true)
;
爲何要用Lifecycle.State.STARTED
?由於這裏本質上用的是add
+Lifecycle.State.STARTED
和attach
+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
生命週期,一句話形容就是對add
、attach
等命令的補充;
其次該功能在官方控件中得以運用,改善了ViewPager
+Fragment
的使用體驗,懶加載注意點;
最後鼓勵你們(主要是本身)多看源碼,夯實基礎,方能不變應萬變,本文結束。