关于Fragment的生命周期,博主写过Activity与Fragment生命周期详解,基本上把Fragment的生命周期详细介绍过,但是那仅仅是创建一个Fragmnet时的生命周期,而事实上Fragment的出现是为了动态的切换显示不同的界面的,因此我们对于Fragment的生命周期的了解不能仅仅停留在创建一个Fragment的时候,而是应该能够知道调用不同API切换Fragment时的生命周期是怎么的,如调用add(),hide(),show()与replace()时它们的生命周期的不同,博主在昨天360视频面试的时候就被问到过。

一使用静态方式时的生命周期:

正如我们在Activity与Fragment生命周期详解中所介绍的,此时Fragment的生命周期为

onAttach, onCreate, onCreateView, onActivityCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach.

可以参看Activity与Fragment生命周期详解中相关内容的官方图片理解,

1其中当创建一个Fragment首次展示其布局界面时:

onAttach, onCreate, onCreateView, onActivityCreated, onStart, onResume,Fragment处于运行状态

2当关闭手机屏幕或者手机屏幕变暗或直接按home键返回桌面时,其生命周期方法调用的顺序是

onPause, onStop

3当再次对手机屏幕解锁或者手机屏幕变亮时,其生命周期方法调用的顺序:

onStart, onResume

4当对Fragment按返回键时:

onPause, onStop, onDestroyView, onDestroy, onDetach.


二使用FragmentManager动态的添加Fragment

这块是本博客讲解的重点,因为动态添加涉及到Fragment的切换,所以我们先定义两个Fragment。代码如下:

public class FragOne extends Fragment {private static final String TAG = FragOne.class.getSimpleName();@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);Log.i(TAG, "onAttach");}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.i(TAG, "onCreate");}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {Log.i(TAG, "onCreateView");return inflater.inflate(R.layout.fragment_test_a, null, false);}@Overridepublic void onViewCreated(View view, Bundle savedInstanceState) {Log.i(TAG, "onViewCreated");super.onViewCreated(view, savedInstanceState);}@Overridepublic void onDestroy() {Log.i(TAG, "onDestroy");super.onDestroy();}@Overridepublic void onDetach() {Log.i(TAG, "onDetach");super.onDetach();}@Overridepublic void onDestroyView() {Log.i(TAG, "onDestroyView");super.onDestroyView();}@Overridepublic void onStart() {Log.i(TAG, "onStart");super.onStart();}@Overridepublic void onStop() {Log.i(TAG, "onStop");super.onStop();}@Overridepublic void onResume() {Log.i(TAG, "onResume");super.onResume();}@Overridepublic void onPause() {Log.i(TAG, "onPause");super.onPause();}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {Log.i(TAG, "onActivityCreated");super.onActivityCreated(savedInstanceState);}
}

第二个Fragment

public class FragTwo extends Fragment {private static final String TAG = FragTwo.class.getSimpleName();@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);Log.i(TAG, "onAttach");}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.i(TAG, "onCreate");}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {Log.i(TAG, "onCreateView");return inflater.inflate(R.layout.fragment_test_b, null, false);}@Overridepublic void onViewCreated(View view, Bundle savedInstanceState) {Log.i(TAG, "onViewCreated");super.onViewCreated(view, savedInstanceState);}@Overridepublic void onDestroy() {Log.i(TAG, "onDestroy");super.onDestroy();}@Overridepublic void onDetach() {Log.i(TAG, "onDetach");super.onDetach();}@Overridepublic void onDestroyView() {Log.i(TAG, "onDestroyView");super.onDestroyView();}@Overridepublic void onStart() {Log.i(TAG, "onStart");super.onStart();}@Overridepublic void onStop() {Log.i(TAG, "onStop");super.onStop();}@Overridepublic void onResume() {Log.i(TAG, "onResume");super.onResume();}@Overridepublic void onPause() {Log.i(TAG, "onPause");super.onPause();}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {Log.i(TAG, "onActivityCreated");super.onActivityCreated(savedInstanceState);}
}

可以看到这两个Fragment的代码基本上完全相同,都是重写了Fragment中相关的生命周期函数。

一当没使用addToBackStack函数时。

1使用replace()函数时:

当我们使用replace初次显示一个Fragment时,此时代码如下:

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();fragOne = new FragOne();fragmentTransaction.replace(R.id.frag_container, fragOne, fragNames[0]);fragmentTransaction.commit();

此时的生命周期和上述讲述的完全相同,即onAttach, onCreate, onCreateView, onActivityCreated, onStart, onResume,Fragment处于运行状态。

当我们使用replace()来替换一个已经存在的Fragment时(如腾讯QQ中当我们点击不同的底部按钮时会替换之前的Fragment),此时代码如下:

public void onClick(View v) {FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();switch (v.getId()) {case R.id.button1:if (fragOne == null) {fragOne = new FragOne();fragmentTransaction.replace(R.id.frag_container, fragOne, fragNames[0]);
//                    fragmentTransaction.addToBackStack(fragNames[0]);} else {Fragment fragment = fragmentManager.findFragmentByTag(fragNames[0]);fragmentTransaction.replace(R.id.frag_container, fragment, fragNames[0]);}break;case R.id.button2:if (fragTwo == null) {fragTwo = new FragTwo();fragmentTransaction.replace(R.id.frag_container, fragTwo, fragNames[1]);
//                    fragmentTransaction.addToBackStack(fragNames[1]);} else {Fragment fragment = fragmentManager.findFragmentByTag(fragNames[1]);fragmentTransaction.replace(R.id.frag_container, fragment, fragNames[1]);}break;default:break;}fragmentTransaction.commit();}

可以看到在上述代码中,我们将addToBackStack函数的调用注释起来,表示此时不适用该功能。此时的运行顺序为:


可以看到第一个Fragment的调用顺序为:onPause, onStop, onDestroyView, onDestroy, onDetach,这表明fragOne已经被FragmentManager销毁了,取而代之的是第二个Fragment,这也与replace()函数的名称和不适用addToBackStack相符合(即替换且不添加到Fragment返回栈中,既然是替换当然得去除前一个,添加第二个Fragment)

这说明,在使用replace添加Fragment时如果没有调用addToBackStack方式的话,当FragmentManager替换Fragment时,是不保存Fragment的状态的,此时第二个Fragment将会直接替换前一个Fragment。

二使用addToBackStack函数时。

当我们使用replace函数且设置addToBackStack函数初次显示一个Fragment运行结果为:onAttach, onCreate, onCreateView, onActivityCreated, onStart, onResume,Fragment处于运行状态。即与不使用addToBackStack函数时的运行结果相同。

当我们使用replace函数且设置addToBackStack函数来替换之前显示的Fragmen't时运行结果为:

可以看到与之前的不使用addToBackStack相比,fragTwo的生命周期不受影响,而fragOne的生命周期和不使用addBackToStack函数相比,只存在三种状态的切换:onPause

onStop,onDestroyView。前者很好理解,因为addToBackStack函数顾名思义就是添加到回退栈中的意思,即当一个Fragment被另一个Fragment替换时会将之前的添加到回退栈中,因此也很好理解fragTwo的生命周期不受影响,因为是将被替换的添加到回退栈中,所以替换者不受影响。另外fragOne状态只到达onDestroyView,而无onDestroy,

onDetach。这说明fragOne仅仅只是界面被销毁onDestroyView,而fragOne对象的实例依然被保存在FragmentManager中(因为无onDestroy,onDetach),它的部分状态依然被保存在FragmentManager中。我们可以来验证一下:

我们点击按钮切换,让fragOne来替换当前显示的fragTwo,此时运行结果如下:

可以看到此时运行结果与fragTwo替换fragOne时fragOne的生命周期调用顺序非常相似,而且可以看到fragOne的生命周期是直接从onCreateView开始的,这也刚好对应上面的fragOne被fragTwo替换时生命周期到达onDestroyView,即之前的fragOne仅仅销毁了视图,而fragOne对象的实例依然被保存在FragmentManager中,所以此时只需要创建视图,即直接从onCreateView开始。

三使用show()/hide()函数时:首先要明白使用show()/hide()时一般是会使用addToBackStack,,因为要使用show()/hide()前提是该Fragment实例已经存在,只不过我们是否将其界面显示出来而已,因此我们需要使用addToBackStack函数将一个Fragment的实例对象保存在Fragment的回退栈中。此时代码如下:

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();switch (v.getId()) {case R.id.button1:hideAllFrags(fragmentTransaction);if (fragA == null) {fragOne = new FragOne();fragmentTransaction.add(R.id.frag_container, fragOne, fragNames[0]);fragmentTransaction.addToBackStack(fragNames[0]);} else {fragmentTransaction.show(fragOne);}break;case R.id.button2:hideAllFrags(fragmentTransaction);if (fragTwo == null) {fragTwo = new FragTwo();fragmentTransaction.add(R.id.frag_container, fragTwo, fragNames[1]);fragmentTransaction.addToBackStack(fragNames[1]);} else {fragmentTransaction.show(fragTwo);}break;default:break;}
fragmentTransaction.commit();

当我们使用add()/show()函数初次显示一个Fragment运行结果为:onAttach, onCreate, onCreateView, onActivityCreated, onStart, onResume,Fragment处于运行状态。这个很好理解,不再赘述。

当我们点击按钮切换显示第二个Fragment时运行结果为:

可以看到此时fragOne无输出,表示fragOne的生命周期不受影响,而fragTwo的输出结果与直接初次显示fragTwo时是一样的。其实这也很好理解因为在add()/show()/hide()顾名思义就是添加显示隐藏的意思,它都不会对另外的Fragment的生命周期起作用。

转载于:https://www.cnblogs.com/hainange/p/6334027.html

Fragment生命周期详解相关推荐

  1. android fragment生命周期图,Fragment生命周期详解

    序言 Fragment从Android v3.0版本开始引入的,随着界面布局的复杂化,处理起来也更加的复杂,引入Fragment可以把Activity拆分成多个部分.一个Activity可以同时组合多 ...

  2. Fragment的懒加载与生命周期详解

    提示:本文仅为笔者学习记录 Fragment的懒加载与生命周期详解 什么是懒加载 了解Fragment的生命周期 onAttach onCreate onCreateView onActivityCr ...

  3. Android Activity 生命周期详解及监听

    前言 系列文章: Android Activity 与View 的互动思考 Android Activity 生命周期详解及监听 Android onSaveInstanceState/onResto ...

  4. Android面试之Activity生命周期详解

    Activity生命周期详解 一 Activity的四种状态: Activity的生命周期中存在四种基本的状态:活动状态(Active/Runing),暂停状态(Paused),停止状态(Stoppe ...

  5. vue 声明周期函数_Vue 生命周期详解

    Vue 生命周期详解 Vue 生命周期流程 最开始,用户使用 new Vue() 创建根 Vue 实例,或者 Vue 实例化子组件都会调用_init方法(我们将这两种实例都称为vm): functio ...

  6. 01.软件项目管理与敏捷方法——敏捷项目生命周期详解笔记

    01.软件项目管理与敏捷方法--敏捷项目生命周期详解笔记 00.与其说是船还不如说是熟练的航行技术保证了成功的航行.--George William Curtis 01.敏捷项目是一个按照敏捷宣言宗旨 ...

  7. taro生命周期详解

    taro生命周期详解 taro介绍 生命周期 react的钩子函数 为兼容小程序的钩子函数 个别生命周期详解以及注意 1.render()函数 2.constructor()构造函数 3.在各个生命周 ...

  8. Eclipse中Maven常用命令以及Maven生命周期详解

    Eclipse中maven常用的命令 在某一个maven项目右键快捷方式,然后点击Run As就可以发现几个Maven的命令: Maven Build: 这个命令用于编译Maven工程,执行命令后会在 ...

  9. Spring 生命周期详解

    Spring 生命周期详解 一.传统JAVA bean的生命周期 使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了. 一旦bean不再被使用,则由Java自动进行垃圾回 ...

最新文章

  1. 进行xlsx 复制一行_利用Phyton对Excel数据进行查错
  2. 基于区块链技术的数据资产管理机制研究
  3. redis热点key解决方案_缓存穿透,缓存雪崩,4种解决方案分析
  4. onDraw(canvas)和dispatchDraw(canvas)方法
  5. mysql库表的触发器表名_MySQL 触发器,实现不同数据库,不同表名,表结构不同,数据实时同步...
  6. python supervisor_Supervisor捕获不到python的Print
  7. SCI等英文文献免费下载方法总结
  8. 批量将多个 PDF 文件合并成一个独立的 PDF 文件
  9. 全面了解#中国加密艺术圈、元宇宙和就业
  10. Array和Slices
  11. Linux 中断(IRQ/softirq)基础:原理及内核实现
  12. 理解虚拟机(Android 虚拟机进化史)
  13. 【机器学习】课程设计布置:某闯关类手游用户流失预测
  14. 微信公众平台开发(56)优惠券
  15. 【GTASA】如何解锁Locked的DFF模型
  16. 【Java设计模式】简单学抽象工厂模式——你好,微信还是支付宝
  17. 新手村 Boss战-入门综合练习2 小鱼会有危险吗
  18. 区块链与分布式数据库的区别
  19. 浅谈静电场的边值问题(包括数学物理方法和数值计算)
  20. 医院就诊系统-C语言

热门文章

  1. python 选择不同数据库环境执行SQL文件
  2. 【】python时间处理;PYTHON定时任务合集
  3. 在线富文本编辑器 UMeditor
  4. NGUI ListEventDelegate 小坑
  5. 使用sql*plus导出数据表为excel或者html
  6. 雅虎向阿里巴巴示好原因有二
  7. C语言 —— 关键字(C语言标准定义的32个关键字:auto、register、static、sizeof、signed、unsigned 、break 、 continue 、void)
  8. [Poetize6] IncDec Sequence
  9. 华为代码质量军规 (1) 数组访问,必须进行越界保护
  10. 学习的一周?【8.5进度报告】