摘要:前言寫上一篇軟文時(shí),我發(fā)現(xiàn)最新的代碼淘汰了方法,轉(zhuǎn)而支持用方法,言外之意是設(shè)置最大生命周期,懂行的人應(yīng)該知道,一直都是無法直接設(shè)置生命周期,必須通過方法間接干預(yù),本來就此功能,簡(jiǎn)單介紹一下的原理和上手效果閱讀指南本文基于版本的進(jìn)行,也是支
前言寫上一篇ViewPager2軟文時(shí),我發(fā)現(xiàn)最新的Fragment代碼淘汰了setUserVisibleHint方法,轉(zhuǎn)而支持用setMaxLifecycle方法,setMaxLifecycle言外之意是設(shè)置最大生命周期,懂行的人應(yīng)該知道,Fragment一直都是無法直接設(shè)置生命周期,必須通過add、attach、remove、detach、show、hide方法間接干預(yù),本來就此功能,簡(jiǎn)單介紹一下setMaxLifecycle的原理和上手效果;
閱讀指南:
本文基于androidx 1.1.0-alpha07版本的fragment進(jìn)行,也是支持setMaxLifecycle的最低版本
本文會(huì)根據(jù)FragmentPagerAdapter進(jìn)行setMaxLifecycle示例應(yīng)用講解
基本介紹setMaxLifecycle定義在FragmentTransaction中,和之前的add、attach、remove、detach、show、hide等方法是并列關(guān)系;
FragmentTransaction
public FragmentTransaction setMaxLifecycle(@NonNull Fragment fragment,
@NonNull Lifecycle.State state) {
addOp(new Op(OP_SET_MAX_LIFECYCLE, fragment, state));
return this;
}
參數(shù)解讀:
fragment 即需要操作的Fragment對(duì)象,前提條件是這個(gè)fragment必須已經(jīng)加到FragmentManager中;
state Lifecycle.State枚舉類型,該參數(shù)的使用條件是至少是Lifecycle.State.CREATED,否則報(bào)IllegalArgumentException異常
Lifecycle.State一共有五個(gè)狀態(tài),最低要求是Lifecycle.State.CREATED,所以該方法可用的參數(shù)有CREATED、STARTED、RESUMED,State和生命周期方法有何區(qū)別,下面簡(jiǎn)單解釋一下:
生命周期狀態(tài)理解在Fragment中,定義了五種State,這里的State并非上面說Lifecycle.State,但是邏輯基本上是一致的;
INITIALIZING 初始狀態(tài)
CREATED 已創(chuàng)建狀態(tài)
ACTIVITY_CREATED?完全創(chuàng)建,但是沒有started
STARTED 創(chuàng)建并啟動(dòng),可見不可操作
RESUMED 創(chuàng)建啟動(dòng)并可操作
本文內(nèi)容只對(duì)CREATED、STARTED、RESUMED這三個(gè)狀態(tài)講解,由于Fragment中定義的mState和Lifecycle.State不是同一狀態(tài),在本文視為同一概念;
與生命周期對(duì)應(yīng)關(guān)系各位肯定都知道Fragment生命周期有onDestory,onStop等方法,但是狀態(tài)卻沒有這么多,那么如何標(biāo)識(shí)狀態(tài)和對(duì)應(yīng)關(guān)系,下面給出對(duì)應(yīng)關(guān)系;
首先,我把生命周期方法從onCreate->onCretateView->onStart->onResume->onPause->onStop-> onDestoryView->onDestory視為從小到大排序;
同樣的,我們把生命周期狀態(tài)CREATED->STARTED->RESUMED視為從小到大排序;
CREATED狀態(tài)
CREATED即已創(chuàng)建狀態(tài),狹義的理解是生命周期方法走到onCreate,如果當(dāng)前fragment狀態(tài)已大于CREATED,則會(huì)使fragment生命周期方法走到onDestoryView,如果小于CREATED,則走到onCreate;所以CREATED有兩種情況;
STARTED狀態(tài)
同理,STARTED狀態(tài)也有兩種情況,如果當(dāng)前fragment狀態(tài)已大于STARTED,則會(huì)使fragment生命周期方法走到onPause,如果小于CREATED,則走到onStart;
RESUMED狀態(tài)
RESUMED表示的狀態(tài)比較特殊,只代表onResume狀態(tài),無論大到小還是小到大,最終都是停留到onResume狀態(tài);
以上生命周期狀態(tài)扭轉(zhuǎn)結(jié)論基于FragmentManagerImpl.moveToState()方法提取,如有誤導(dǎo),請(qǐng)指教
如何使用setMaxLifecycle可以多帶帶使用,也可以配合add等方法組合使用,首先,我們分析多帶帶執(zhí)行add命令的狀態(tài)變化:
多帶帶執(zhí)行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();
對(duì)RESUMED狀態(tài)的Fragment進(jìn)行操作CREATED操作
對(duì)RESUMED狀態(tài)的Fragment進(jìn)行操作STARTED操作
對(duì)RESUMED狀態(tài)的Fragment進(jìn)行操作CREATED操作,在進(jìn)行STARTED操作
由于篇幅原因,就不一一介紹各種組合情況,只要弄清楚生命周期狀態(tài),不論是狀態(tài)是升還是降,不論組合還是單用,你都可以駕馭;
FragmentPagerAdapter變動(dòng)由于setMaxLifecycle帶來了生命周期設(shè)置,替換掉了老舊的setUserVisibleHint方法,所以在FragmentPagerAdapter中也進(jìn)行了適配
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用一個(gè)mBehavior來控制setUserVisibleHint和setMaxLifecycle二選一的局面; mBehavior在構(gòu)造方法中指定;
從代碼可以看出,用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組合;
最終的結(jié)果是不可見的Fragment只會(huì)走到生命周期onStart方法,不會(huì)走onResume方法;
懶加載新方案綜上,過去使用setUserVisibleHint來控制Fragment懶加載,在最新版的FragmentPagerAdapter里有新思路,可以切換到BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT模式,在FragmentonResume里判斷,更符合顯示邏輯;
切換到BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT模式,需要調(diào)用倆參數(shù)的構(gòu)造方法:
new FragmentPagerAdapter(getSupportFragmentManager(),FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)總結(jié)
破事水了小半天,本文到底說了什么內(nèi)容,還是做個(gè)總結(jié)吧:
首先使用setMaxLifecycle能進(jìn)一步的控制Fragment生命周期,一句話形容就是對(duì)add、attach等命令的補(bǔ)充;
其次該功能在官方控件中得以運(yùn)用,改善了ViewPager+Fragment的使用體驗(yàn),懶加載注意點(diǎn);
最后鼓勵(lì)大家(主要是自己)多看源碼,夯實(shí)基礎(chǔ),方能不變應(yīng)萬變,本文結(jié)束。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/7279.html
閱讀 1397·2021-11-24 09:38
閱讀 3325·2021-11-22 12:03
閱讀 4350·2021-11-11 10:59
閱讀 2423·2021-09-28 09:36
閱讀 1103·2021-09-09 09:32
閱讀 3554·2021-08-05 10:00
閱讀 2618·2021-07-23 15:30
閱讀 3050·2019-08-30 13:12