首先,我们创建一个Activity和一个Fragment,并在Fragment的各个生命周期打好日志,并把Fragments丢进Viewpager,这里我们往Viewpager里丢了3个Fragment,够用了。

同时设置Viewpager.adapter = FragmentPagerAdapter

0.刚打开Avtivity

viewpager刚进入时刻:viewpager显示fragment1,fragment2同时被预加载,currentItem = 0

1.往左翻动一页

此时滑动一页来到第二页,currentItem = 1,可以看到前2个fragment没有生命周期的变化,只是第三个faragment走了一遍前2个走过的路,这里大家也都知道,viewpager有个setOffscreenPageLimit()方法,用来确认左右两边同时各加载几个页面,默认为1,这里adapter.getCount()==3所有滑到中间的时候,所有页面都是在活跃的状态,所以前两个页面不会有生命周期的调用。

2.继续往左翻动一页

再次滑到下一页,currentItem = 2 可以看到第2、3个页面生命周期没有变化,只有第一个页面经历了onPause->onStop->onDestroyView这么一个变化。第一个页面的视图被销毁了。

3.往右翻动一页

此时currentItem=1,可以看到第一个页面的Fragment的视图重建了,从onCreateView开始走一遍。不过并没有经历onAttach/onCreate。

4.按返回键退出Activity

fragment生命周期有这些变化,可以看到第2、3个页面也走过了onPause->onStop->onDestroyView这么一个变化,由于第一个页面在上一步就销毁了view走过了这个步骤,所以接下来就是所有的Fragment经历onDestroy->onDetach这么一个过程


接下来设置viewpager.adapter = FragmentStatePagerAdapter

0.首先,老规矩,刚打开Activity时候的状态

可以看到没有任何一点变化,跟上面同时期的状态是一毛一样的。currentItem = 0

1.往左翻动一页

可以看到,跟上面同时期还是没有any变化......currentItem = 1

2.继续往左翻动一页

好吧,咱继续翻,currentItem = 2,这里有区别了:可以看到第一个页面还是经过了onPause->onStop->onDestoryView这么一个过程,不过在此之前,调用了onSaveInstanceState来保存一些必要的信息,在此后,该fragment也随即从内存中销毁,因为经过了onDestroy->onDetach这么一个过程,与activity脱离关系。那么我们再往右滑动一页,回到currentItem=1的时候。

3.往右翻动一页

可以看到此时第一个页面的fragment重建了,重新走了一遍onAttach->...->onResume这么个过程,并且在其中有传入saveInstanceState的方法中传入了一个不为null的对象,日志中我们可以看到bundle中有个testKey=0,是因为我们重写了fragment的一个方法:

 override fun onSaveInstanceState(outState: Bundle?) {super.onSaveInstanceState(outState)outState?.putInt("testKey",arguments.getInt("index"))log("onSaveInstanceState")}

这里arguments中的int extra是自己传进去的。

那么我们看下FragmentStateViewPager的源码:

 @Overridepublic Object instantiateItem(ViewGroup container, int position) {...if (mSavedState.size() > position) {Fragment.SavedState fss = mSavedState.get(position);if (fss != null) {fragment.setInitialSavedState(fss);}}while (mFragments.size() <= position) {mFragments.add(null);}...return fragment;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {while (mSavedState.size() <= position) {mSavedState.add(null);}mSavedState.set(position, fragment.isAdded()? mFragmentManager.saveFragmentInstanceState(fragment) : null);mFragments.set(position, null);...}

省略掉无关代码,就剩下以上这些,可以看到FragmentStateViewPager$destroyItem中为我们保存了Fragment退出时的状态,而在FragmentStateViewPager$instantiateItem中为新建的Fragment设置了初始化state,以此达到为我们保存Fragment state的目的。

总结 FragmentPagerAdapter&FragmentStatePagerAdapter:

相似点:

他们都无法保存视图,即在offScreenLimit之外的Fragment总是要被destroyView。

不同点:

最大的区别就是对于在offScreenLimit之外的Fragment,FragmentPagerAdapter会销毁试图,但Fragmnet不会detach,也就是Fragment还是在内存中的,当需要再次显示时他会createView,这意味着我们可以在Fragment对象中保存一些我们需要存储的信息,createView的时候做自己的选择。

而FragmentStatePagerAdapter就不同了,相同的情况下对于在offScreenLimit之外的Fragment,被destroyView只有还有detach,也就是此前的Fragment对象不复存在了,那么我们肯定不能在Fragment中保存必要的信息了,此时可以重写onSaveInstanceState来保存必要信息,并在onCreateView的时候重新拿出来用。FragmentStatePagerAdapter中为我们保存这些state是通过一个ArrayList来实现的,意味着他是记着Fragment的index作为key来保存或者取出的,


那么对于我们开发者来说,可以在此做个选择。在使用Viewpager中Fragment页面较少的情况可以选择FragmentPagerAdapter,这样代码会少几行,简单。

在viewpager中Fragment页面比较多的时候选择FragmentStatePagerAdapter来减少内存占用,Fragment试图销毁的同时detach Fargment,但需要通过saveInstaceState来达到保存关键信息的目的。

至于Fragment的生命周期,关键的应该都已经在上面出现过了,有时间再添加上hide/show/repalce时候的生命周期。

ViewPager中Fragment的生命周期和FragmentPageAdapter与FragmentStatePageAdapter对其的影响相关推荐

  1. android viewpager fragment 生命周期,ViewPager中Fragment的生命周期

    网上有很多Fragment生命周期的帖子,但是看了一下,没有找到自己想了解的东西,于是决定自己动手体验一下这个生命周期.主要想了解以下几个问题: Activity中的Fragment的生命周期 Vie ...

  2. 友盟页面统计 - 关于Viewpager中的Fragment的生命周期

    Activity和Fragment各自理论上的生命周期 Activity的生命周期是较为经典也最清晰的,在此不表: Fragment从出现到广泛运用也有一段时间了,其标准生命周期也仅比Activity ...

  3. Android应用开发—ViewPager FragmentPagerAdapter和FragmentStatePagerAdapter下Fragment的生命周期

    ViewPager配合不同的PagerAdapter,对应Fragment的生命周期有着不同的表现,了解这个生命周期机制对于开发者选择合适的PagerAdapter实现不同的效果,有着很大的帮助. F ...

  4. ViewPager与Fragment结合使用,以及切换的时候Fragment 的生命周期

    下面要做的效果图下图 首先我们创建一个适配器如下 public class FraPagerAdapter extends FragmentPagerAdapter {private List< ...

  5. Fragment 的生命周期

    Fragment的生命周期,按照正常顺序来看依次是: onAttach(),老式的方法是以Activity为参数,后来改成了context做参数.但是其实我实际项目中并没有重写这一方法,因为其父类方法 ...

  6. ViewPager中Fragment的重复创建、复用问题

    在ViewPager中的Fragment的生命周期  随着页面的切换 当前的展示页相邻的页面生命周期一直在变化 一开始 刚进入Activity时候,ViewPager默认初始化好前两个Fragment ...

  7. Activity与Fragment的生命周期详解

    在安卓中Activity与Fragment是非常相似的两个类,它们各自都拥有自己的生命周期,且都可以用来显示布局文件中的视图.其中Activity是通过setContenView()显示视图,而Fra ...

  8. Android系列之Fragment(二)----Fragment的生命周期和返回栈

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  9. 安卓APP_ Fragment(3)—— Fragment的生命周期

    摘自:安卓APP_ Fragment(3)-- Fragment的生命周期 作者:丶PURSUING 发布时间: 2021-04-16 22:32:12 网址:https://blog.csdn.ne ...

最新文章

  1. 【深度学习】一个应用—肝脏CT图像自动分割(术前评估)
  2. boot spring test 文档_SpringBoot入门建站全系列(五)使用Spring-data-jpa操作数据库
  3. c语言 文件f指针,C语言文件选择题
  4. skywalking 引起 spring-cloud-gateway 的内存溢出 skywalking的bug
  5. 微软中国:Morro可能将不进入中国市场
  6. mysql配置好后_安装完 MySQL 后必须调整的 10 项配置
  7. 开源demo| 你画我猜——让你的生活更有趣
  8. 九层之台,起于累土:码良组件开发
  9. excel中图片链接利用宏VB转换为图片展示
  10. 怎么把html文档转换成wps,怎么把wps文档转换成word文档
  11. Python学习笔记:part 1
  12. jira是干什么_Jira 概述 | 产品、项目和托管 | Atlassian
  13. 强袭自由高达,我的第一个作品
  14. Repository “http://xxx@git.xxx.net/xxx/xxx.git”not found 解决
  15. 中国工程院院士高文:从大数据科学到人工智能的迁移过程
  16. 五个经典漏斗模型,看漏斗思维穿透流程化的本质
  17. 计算机组成原理笔试,农村信用社招聘笔试--计算机组成原理重点总结.doc
  18. wordpress mysql 5.7_CentOS7 运维 - 搭建WordPress论坛 | 超详细 | MySQL安装使用
  19. Win 10 安装手机驱动
  20. 使用ZVS驱动无线充电线圈

热门文章

  1. C++、C#控制台应用程序暂停下来的方法
  2. 产生0到1之间均匀分布的一个随机数原理与实现
  3. mysql命令技巧_Mysql命令行技巧汇总
  4. centos 7.6安装java_Docker安装zabbix5.0LTS教程和优化
  5. git gui fetch不到文件_Git内部原理剖析,有比这还详细的吗?
  6. enq: tt - contention_要签TT或伊巴卡?湖人要走一步大棋,大肆招揽老将,为老詹真拼...
  7. ASP.NET MVC中你必须知道的13个扩展点
  8. 内核随记(三)--同步(2)【转】
  9. python之初接触
  10. CentOS 6.0 VNC远程桌面配置