Fragment的生命周期
Fragment生命周期AndroidX之前的Fragment
在AndroidX之前的Fragment , 由于配合ViewPager使用 , 在Fragment添加到ViewPager上后 , 生命周期会跟Activity绑定 , 所以导致Fragment在不可见的时候 , onStart/onResume也会被回调 .
于是 , 在配合setOffscreenPageLimit
预加载的时候 , 由于早期版本的ViewPager至少需要预加载右侧一个页面 , 所以导致在实现懒加载的过程中需要通过 :
- setUserVisibleHint : 当Fragment显示/不可见的时候会回调显示状态(isVisible)
- onResume : 在该回调中判断当前Fragment是否可见 , 如果可见的话 , 进行懒加载
只有通过以上两个方法来进行懒加载.
ViewPager2与Fragment配合使用
在ViewPager2中 , 官方将Fragment的生命周期纠正了 , 可以随着ViewPager2的左右切换来回调Fragment当前的状态. 以下是ViewPager2与Fragment配合的代码 , 在生命周期中加入Log.
其中ViewPager.offscreenPageLimit = 2
设置为2
class CardFragmentActivity : BaseCardActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 设置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设置Adapter的生命周期回调
- 在
setAdapter
之后 , ViewPager会回调onAttach
、onCreate
、onCreateView
、onActivityCreate
、onStart
- 当前显示的Fragment会回调
onResume
- 由于
offscreenPageLimit
为2 , 所以会预先初始化后面两个Fragment
// 初始化第一个Fragment
E/CardFragmentTag: onAttach:f0
E/CardFragmentTag: onCreate:f0
E/CardFragmentTag: onCreateView:CardFragment{7ccd71c} f0}
E/CardFragmentTag: onActivityCreated:f0
E/CardFragmentTag: onStart:f0
// 当前展示的Fragment , 所以会回调onResume ,展示当前Fragment
E/CardFragmentTag: onResume:f0
// 初始化第二个Fragment
E/CardFragmentTag: onAttach:f1
E/CardFragmentTag: onCreate:f1
E/CardFragmentTag: onCreateView:CardFragment{3bdad9} f1}
E/CardFragmentTag: onActivityCreated:f1
E/CardFragmentTag: onStart:f1
// 初始化第三个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
设置为2 , 所以第四页会预加载至onStart
状态 - 预加载完后 , 才会让
f1
回调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)
- 当页面缓存超过
7
个时 , 会将最后使用的Fragment销毁回收 - 优先创建操作 , 然后再进行回收 , 最后进行展示
// 创建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
// 向右滑动一页 , 创建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
// 向右滑动一页 , 创建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
// 向右滑动一页 , 创建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
// 向右滑动一页 , 创建f7
E/CardFragmentTag: onAttach:f7
E/CardFragmentTag: onCreate:f7
E/CardFragmentTag: onCreateView:CardFragment{f40a602} f7}
E/CardFragmentTag: onActivityCreated:f7
E/CardFragmentTag: onStart:f7
// 在创建完f7后 , 会回收f0
E/CardFragmentTag: onStop:f0
E/CardFragmentTag: onDestroyView:f0
E/CardFragmentTag: onDestroy:f0
// 当前展示f5
E/CardFragmentTag: onResume:f5
4. 回到桌面/锁屏
- 当Activity回到桌面或者锁屏后 , 开始按顺序回调当前缓存中的Fragment的
onStop
- 最后再回调当前页面的
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
状态 , 所以当划过去之后 , 只会回调onResume
- 由于向左滑动超过缓存数量 ,所以
f7
会被回收
// 向左滑一页
E/CardFragmentTag: onResume:f4
// 向左滑一页
E/CardFragmentTag: onResume:f3
// 向左滑一页后 , 由于之前f0被回收 ,所以会先创建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键回到上一页
- 会顺序先回调
onStop
, 再调用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
网友评论