ViewPager中Fragment的生命周期和FragmentPageAdapter与FragmentStatePageAdapter对其的影响
首先,我们创建一个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对其的影响相关推荐
- android viewpager fragment 生命周期,ViewPager中Fragment的生命周期
网上有很多Fragment生命周期的帖子,但是看了一下,没有找到自己想了解的东西,于是决定自己动手体验一下这个生命周期.主要想了解以下几个问题: Activity中的Fragment的生命周期 Vie ...
- 友盟页面统计 - 关于Viewpager中的Fragment的生命周期
Activity和Fragment各自理论上的生命周期 Activity的生命周期是较为经典也最清晰的,在此不表: Fragment从出现到广泛运用也有一段时间了,其标准生命周期也仅比Activity ...
- Android应用开发—ViewPager FragmentPagerAdapter和FragmentStatePagerAdapter下Fragment的生命周期
ViewPager配合不同的PagerAdapter,对应Fragment的生命周期有着不同的表现,了解这个生命周期机制对于开发者选择合适的PagerAdapter实现不同的效果,有着很大的帮助. F ...
- ViewPager与Fragment结合使用,以及切换的时候Fragment 的生命周期
下面要做的效果图下图 首先我们创建一个适配器如下 public class FraPagerAdapter extends FragmentPagerAdapter {private List< ...
- Fragment 的生命周期
Fragment的生命周期,按照正常顺序来看依次是: onAttach(),老式的方法是以Activity为参数,后来改成了context做参数.但是其实我实际项目中并没有重写这一方法,因为其父类方法 ...
- ViewPager中Fragment的重复创建、复用问题
在ViewPager中的Fragment的生命周期 随着页面的切换 当前的展示页相邻的页面生命周期一直在变化 一开始 刚进入Activity时候,ViewPager默认初始化好前两个Fragment ...
- Activity与Fragment的生命周期详解
在安卓中Activity与Fragment是非常相似的两个类,它们各自都拥有自己的生命周期,且都可以用来显示布局文件中的视图.其中Activity是通过setContenView()显示视图,而Fra ...
- Android系列之Fragment(二)----Fragment的生命周期和返回栈
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- 安卓APP_ Fragment(3)—— Fragment的生命周期
摘自:安卓APP_ Fragment(3)-- Fragment的生命周期 作者:丶PURSUING 发布时间: 2021-04-16 22:32:12 网址:https://blog.csdn.ne ...
最新文章
- 【深度学习】一个应用—肝脏CT图像自动分割(术前评估)
- boot spring test 文档_SpringBoot入门建站全系列(五)使用Spring-data-jpa操作数据库
- c语言 文件f指针,C语言文件选择题
- skywalking 引起 spring-cloud-gateway 的内存溢出 skywalking的bug
- 微软中国:Morro可能将不进入中国市场
- mysql配置好后_安装完 MySQL 后必须调整的 10 项配置
- 开源demo| 你画我猜——让你的生活更有趣
- 九层之台,起于累土:码良组件开发
- excel中图片链接利用宏VB转换为图片展示
- 怎么把html文档转换成wps,怎么把wps文档转换成word文档
- Python学习笔记:part 1
- jira是干什么_Jira 概述 | 产品、项目和托管 | Atlassian
- 强袭自由高达,我的第一个作品
- Repository “http://xxx@git.xxx.net/xxx/xxx.git”not found 解决
- 中国工程院院士高文:从大数据科学到人工智能的迁移过程
- 五个经典漏斗模型,看漏斗思维穿透流程化的本质
- 计算机组成原理笔试,农村信用社招聘笔试--计算机组成原理重点总结.doc
- wordpress mysql 5.7_CentOS7 运维 - 搭建WordPress论坛 | 超详细 | MySQL安装使用
- Win 10 安装手机驱动
- 使用ZVS驱动无线充电线圈
热门文章
- C++、C#控制台应用程序暂停下来的方法
- 产生0到1之间均匀分布的一个随机数原理与实现
- mysql命令技巧_Mysql命令行技巧汇总
- centos 7.6安装java_Docker安装zabbix5.0LTS教程和优化
- git gui fetch不到文件_Git内部原理剖析,有比这还详细的吗?
- enq: tt - contention_要签TT或伊巴卡?湖人要走一步大棋,大肆招揽老将,为老詹真拼...
- ASP.NET MVC中你必须知道的13个扩展点
- 内核随记(三)--同步(2)【转】
- python之初接触
- CentOS 6.0 VNC远程桌面配置