相关文章推荐
豁达的枇杷  ·  Excel的日期格式约定与解析 - 林博士 ...·  1 年前    · 
曾深爱过的眼镜  ·  Laravel有哪些用户安全认证方式? - 知乎·  1 年前    · 
自信的可乐  ·  Singularity将本地SIF文件,转成 ...·  2 年前    · 
豪情万千的葡萄酒  ·  Android Camera2 API简述 ...·  2 年前    · 
Code  ›  ViewPager2与Fragment开发者社区
viewpager f3 fragment
https://cloud.tencent.com/developer/article/1679982
深沉的山羊
2 年前
作者头像
None_Ling
0 篇文章

ViewPager2与Fragment

前往专栏
腾讯云
备案 控制台
开发者社区
学习
实践
活动
专区
工具
TVP
文章/答案/技术大牛
写文章
社区首页 > 专栏 > Android相关 > 正文

ViewPager2与Fragment

发布 于 2020-08-14 16:17:55
1.9K 0
举报

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
 
推荐文章
豁达的枇杷  ·  Excel的日期格式约定与解析 - 林博士 - 博客园
1 年前
曾深爱过的眼镜  ·  Laravel有哪些用户安全认证方式? - 知乎
1 年前
自信的可乐  ·  Singularity将本地SIF文件,转成sandbox_周迪新的博客-CSDN博客
2 年前
豪情万千的葡萄酒  ·  Android Camera2 API简述 (五) - 掘金
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号