Fragment的生命周期

Fragment生命周期
AndroidX之前的Fragment
在AndroidX之前的Fragment , 由于配合ViewPager使用 , 在Fragment添加到ViewPager上后 , 生命周期會(huì)跟Activity綁定 , 所以導(dǎo)致Fragment在不可見的時(shí)候 , onStart/onResume也會(huì)被回調(diào) .
于是 , 在配合setOffscreenPageLimit預(yù)加載的時(shí)候 , 由于早期版本的ViewPager至少需要預(yù)加載右側(cè)一個(gè)頁面 , 所以導(dǎo)致在實(shí)現(xiàn)懶加載的過程中需要通過 :
- setUserVisibleHint : 當(dāng)Fragment顯示/不可見的時(shí)候會(huì)回調(diào)顯示狀態(tài)(isVisible)
- onResume : 在該回調(diào)中判斷當(dāng)前Fragment是否可見 , 如果可見的話 , 進(jìn)行懶加載
只有通過以上兩個(gè)方法來進(jìn)行懶加載.
ViewPager2與Fragment配合使用
在ViewPager2中 , 官方將Fragment的生命周期糾正了 , 可以隨著ViewPager2的左右切換來回調(diào)Fragment當(dāng)前的狀態(tài). 以下是ViewPager2與Fragment配合的代碼 , 在生命周期中加入Log.
其中ViewPager.offscreenPageLimit = 2設(shè)置為2
class CardFragmentActivity : BaseCardActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 設(shè)置offscreenPageLimit為2
viewPager.offscreenPageLimit = 2
viewPager.adapter = object : FragmentStateAdapter(this) {
override fun createFragment(position: Int): Fragment {
return CardFragment.create(Card.DECK[position])
}
override fun getItemCount(): Int {
return Card.DECK.size
}
}
}
class CardFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.e("CardFragmentTag", "onCreateView:$this")
val cardView = CardView(layoutInflater, container)
cardView.bind(Card.fromBundle(arguments!!))
return cardView.view
}
override fun onAttach(context: Context) {
super.onAttach(context)
Log.e("CardFragmentTag", "onAttach:$tag")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.e("CardFragmentTag", "onCreate:$tag")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Log.e("CardFragmentTag", "onActivityCreated:$tag")
}
override fun onStop() {
super.onStop()
Log.e("CardFragmentTag", "onStop:$tag")
}
override fun onDestroyView() {
super.onDestroyView()
Log.e("CardFragmentTag", "onDestroyView:$tag")
}
override fun onDestroy() {
super.onDestroy()
Log.e("CardFragmentTag", "onDestroy:$tag")
}
override fun onStart() {
super.onStart()
Log.e("CardFragmentTag", "onStart:$tag")
}
override fun onResume() {
super.onResume()
Log.e("CardFragmentTag", "onResume:$tag")
}
companion object {
/** Creates a Fragment for a given [Card] */
fun create(card: Card): CardFragment {
val fragment = CardFragment()
fragment.arguments = card.toBundle()
return fragment
}
}
}
}
1. ViewPager2設(shè)置Adapter的生命周期回調(diào)
- 在
setAdapter之后 , ViewPager會(huì)回調(diào)onAttach、onCreate、onCreateView、onActivityCreate、onStart - 當(dāng)前顯示的Fragment會(huì)回調(diào)
onResume - 由于
offscreenPageLimit為2 , 所以會(huì)預(yù)先初始化后面兩個(gè)Fragment
// 初始化第一個(gè)Fragment
E/CardFragmentTag: onAttach:f0
E/CardFragmentTag: onCreate:f0
E/CardFragmentTag: onCreateView:CardFragment{7ccd71c} f0}
E/CardFragmentTag: onActivityCreated:f0
E/CardFragmentTag: onStart:f0
// 當(dāng)前展示的Fragment , 所以會(huì)回調(diào)onResume ,展示當(dāng)前Fragment
E/CardFragmentTag: onResume:f0
// 初始化第二個(gè)Fragment
E/CardFragmentTag: onAttach:f1
E/CardFragmentTag: onCreate:f1
E/CardFragmentTag: onCreateView:CardFragment{3bdad9} f1}
E/CardFragmentTag: onActivityCreated:f1
E/CardFragmentTag: onStart:f1
// 初始化第三個(gè)Fragment
E/CardFragmentTag: onAttach:f2
E/CardFragmentTag: onCreate:f2
E/CardFragmentTag: onCreateView:CardFragment{d272be4} f2}
E/CardFragmentTag: onActivityCreated:f2
E/CardFragmentTag: onStart:f2
2. 向右翻一頁(即展示Fragment1)
- 由于
offscreenPageLimit設(shè)置為2 , 所以第四頁會(huì)預(yù)加載至onStart狀態(tài) - 預(yù)加載完后 , 才會(huì)讓
f1回調(diào)onResume展示
E/CardFragmentTag: onAttach:f3
E/CardFragmentTag: onCreate:f3
E/CardFragmentTag: onCreateView:CardFragment{31101e6} (2d98fd63-e29c-4f1f-98ff-589291160831) f3}
E/CardFragmentTag: onActivityCreated:f3
E/CardFragmentTag: onStart:f3
E/CardFragmentTag: onResume:f1
3. 向右再翻五頁(即展示Fragment6)
- 當(dāng)頁面緩存超過
7個(gè)時(shí) , 會(huì)將最后使用的Fragment銷毀回收 - 優(yōu)先創(chuàng)建操作 , 然后再進(jìn)行回收 , 最后進(jìn)行展示
// 創(chuàng)建3
E/CardFragmentTag: onAttach:f3
E/CardFragmentTag: onCreate:f3
E/CardFragmentTag: onCreateView:CardFragment{c2875a8} f3}
E/CardFragmentTag: onActivityCreated:f3
E/CardFragmentTag: onStart:f3
// 讓f1顯示
E/CardFragmentTag: onResume:f1
// 向右滑動(dòng)一頁 , 創(chuàng)建f4
E/CardFragmentTag: onAttach:f4
E/CardFragmentTag: onCreate:f4
E/CardFragmentTag: onCreateView:CardFragment{6e11b5} f4}
E/CardFragmentTag: onActivityCreated:f4
E/CardFragmentTag: onStart:f4
// 展示f2
E/CardFragmentTag: onResume:f2
// 向右滑動(dòng)一頁 , 創(chuàng)建f5
E/CardFragmentTag: onAttach:f5
E/CardFragmentTag: onCreate:f5
E/CardFragmentTag: onCreateView:CardFragment{de392ee} f5}
E/CardFragmentTag: onActivityCreated:f5
E/CardFragmentTag: onStart:f5
// 展示f3
E/CardFragmentTag: onResume:f3
// 向右滑動(dòng)一頁 , 創(chuàng)建f6
E/CardFragmentTag: onAttach:f6
E/CardFragmentTag: onCreate:f6
E/CardFragmentTag: onCreateView:CardFragment{711b020} f6}
E/CardFragmentTag: onActivityCreated:f6
E/CardFragmentTag: onStart:f6
// 展示f4
E/CardFragmentTag: onResume:f4
// 向右滑動(dòng)一頁 , 創(chuàng)建f7
E/CardFragmentTag: onAttach:f7
E/CardFragmentTag: onCreate:f7
E/CardFragmentTag: onCreateView:CardFragment{f40a602} f7}
E/CardFragmentTag: onActivityCreated:f7
E/CardFragmentTag: onStart:f7
// 在創(chuàng)建完f7后 , 會(huì)回收f0
E/CardFragmentTag: onStop:f0
E/CardFragmentTag: onDestroyView:f0
E/CardFragmentTag: onDestroy:f0
// 當(dāng)前展示f5
E/CardFragmentTag: onResume:f5
4. 回到桌面/鎖屏
- 當(dāng)Activity回到桌面或者鎖屏后 , 開始按順序回調(diào)當(dāng)前緩存中的Fragment的
onStop - 最后再回調(diào)當(dāng)前頁面的
onStop
E/CardFragmentTag: onCreateView:CardFragment{520735b} f0}
E/CardFragmentTag: onActivityCreated:f0
E/CardFragmentTag: onStart:f0
E/CardFragmentTag: onResume:f2
// 回到桌面/鎖屏后
E/CardFragmentTag: onStop:f1
E/CardFragmentTag: onStop:f2
E/CardFragmentTag: onStop:f3
E/CardFragmentTag: onStop:f4
E/CardFragmentTag: onStop:f5
E/CardFragmentTag: onStop:f6
E/CardFragmentTag: onStop:f7
E/CardFragmentTag: onStop:f0
5. 向左翻兩頁(即展示Fragment4)
- 由于之前的Fragment都處于
onStart狀態(tài) , 所以當(dāng)劃過去之后 , 只會(huì)回調(diào)onResume - 由于向左滑動(dòng)超過緩存數(shù)量 ,所以
f7會(huì)被回收
// 向左滑一頁
E/CardFragmentTag: onResume:f4
// 向左滑一頁
E/CardFragmentTag: onResume:f3
// 向左滑一頁后 , 由于之前f0被回收 ,所以會(huì)先創(chuàng)建f0
E/CardFragmentTag: onAttach:f0
E/CardFragmentTag: onCreate:f0
E/CardFragmentTag: onCreateView:CardFragment{95675ff} f0}
E/CardFragmentTag: onActivityCreated:f0
E/CardFragmentTag: onStart:f0
// 展示f2
E/CardFragmentTag: onResume:f2
// 向左滑一頁后 , 開始回收f7
E/CardFragmentTag: onStop:f7
E/CardFragmentTag: onDestroyView:f7
E/CardFragmentTag: onDestroy:f7
// 展示f1
E/CardFragmentTag: onResume:f1
6. 按Back鍵回到上一頁
- 會(huì)順序先回調(diào)
onStop, 再調(diào)用onDestroyView與onDestroy
E/CardFragmentTag: onStop:f1
E/CardFragmentTag: onStop:f2
E/CardFragmentTag: onStop:f3
E/CardFragmentTag: onStop:f4
E/CardFragmentTag: onStop:f5
E/CardFragmentTag: onStop:f6
E/CardFragmentTag: onStop:f0
E/CardFragmentTag: onDestroyView:f1
E/CardFragmentTag: onDestroy:f1
E/CardFragmentTag: onDestroyView:f2
E/CardFragmentTag: onDestroy:f2
E/CardFragmentTag: onDestroyView:f3
E/CardFragmentTag: onDestroy:f3
E/CardFragmentTag: onDestroyView:f4
E/CardFragmentTag: onDestroy:f4
E/CardFragmentTag: onDestroyView:f5
E/CardFragmentTag: onDestroy:f5
E/CardFragmentTag: onDestroyView:f6
E/CardFragmentTag: onDestroy:f6
E/CardFragmentTag: onDestroyView:f0
E/CardFragmentTag: onDestroy:f0