专栏首页Android相关ViewPager2与Fragment

ViewPager2与Fragment

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会回调onAttachonCreateonCreateViewonActivityCreateonStart
  • 当前显示的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 , 再调用onDestroyViewonDestroy
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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux编程--地址计算

    在学习Matrix的ELF Hook的过程中,发现在查找Library基址指针的时候,对于指针的运算有一些疑惑,特此记录。

    None_Ling
  • MultiDex原理

    MultiDex适用于API版本在4-20的Android系统 , 即Android 2.1 - 4.4 . 而在这些版本之间 , MultiDex会通过App...

    None_Ling
  • B树与B+树(Balance Tree)

    B树的产生是为了: 解决因为大量数据时,红黑树/二叉查找树的深度太深,如数据库的索引数据存放在磁盘上,而如果使用红黑树的话,深度太深,每一个查找一个节点都需要...

    None_Ling
  • Java IO学习笔记(一):File类

    http://www.cnblogs.com/lich/archive/2011/12/10/2283445.html

    bear_fish
  • 工业互联网平台系统:数字化、网络化、智能化架构模式(图文)

    工业互联网平台基于ICT技术打造的开放式平台,聚焦“联接+云”,提供智能化的边缘层、泛在网络、可信IaaS、工业PaaS,及汇聚生态伙伴的工业SaaS, 助力制...

    数商云网络科技
  • Facebook增强版LASER开源:零样本迁移学习,支持93种语言

    【导语】为了加速自然语言处理 (NLP) 在更多语言上实现零样本迁移学习 (zero-shot transfer learning),Facebook 研究者扩...

    AI科技大本营
  • java IO(File类、字节流与字符流、字节字符转换流)

    在整个io包中,唯一表示与文件本身有关的类就是File类。使用File类可以进行创建或删除文件等常用操作,要想使用File类,则首先要观察File类的构造方法...

    qubianzhong
  • 第53节:Java当中的IO流(上)

    在Java中,字符串string可以用来操作文本数据内容,字符串缓冲区是什么呢?其实就是个容器,也是用来存储很多的数据类型的字符串,基本数据类型包装类的出现可以...

    达达前端
  • Kubernetes基础配置

    docker加速 sudo vim /etc/docker/daemon.json

    羊羽shine
  • 在K8s上轻松部署Tungsten Fabric的两种方式

    首先介绍下如何在AWS上使用Kubernetes编排的Tungsten Fabric集群部署沙盒,15分钟就可以搞定。Tungsten Fabric集群由部署节...

    Tungsten Fabric

扫码关注云+社区

领取腾讯云代金券