Android开发笔记 :理解Fragment

news2024/11/23 22:34:35

Android开发笔记:理解Fragment

在这里插入图片描述

导言

本篇文章产生的原因很简单,就是我在了解Android Jetpack中的Lifecycle框架时发现Lifecycle具体时间和状态的更新都是由一个名为ReportFragment的Fragment来跟踪的,为了更好的了解Fragment是如何追踪Activity生命周期状态的变化我们有必要对Fragment组件进行更深入的探讨。

Fragment管理器

首先我们要探讨的就是Fragment管理器(FragmentManager),我们在进行动态地加载和移除Fragment的操作时都需要借助这个Fragment管理器来开启事务,提交请求。Fragment的管理与ViewGroup与View的关系类似,一个Fragment既是上一个父Fragment的子Fragment,又是下一个子Fragment的父Fragment。而每一个父Fragment都有一个FragmentManager来管理其子Fragment。

我们以Google官网上的一张图为例子:
在这里插入图片描述
其中绿色的部分代表的是顶级Activity的布局界面,蓝色部分就是Activity中的Fragment容器了,白色的部分是示例中的最底层的Fragment。在Example 1中Fragment容器中装有两个子Fragment,而每一个父Fragment都有一个FragmentManager,所以例子一种的包含关系和管理关系如下所示:
在这里插入图片描述
对于中间第二级的Fragment,我们即可以通过getParentFragmentManager来获取管理其自身的FragmentManager,还可以通过getChildFragmentManager来获取其管理的Manager。

Fragment事务

所谓的事务,我会把它理解为是一组关于Fragment的操作,我们可以通过beginTransaction方法来开启一个事务,通过这个事务我们可以实现Fragment的添加,移除,替换等操作。当一切操作都添加完毕后我们可以通过commit方法将当前事务给提交。不过,被提交的事务并不会被马上执行,相反的,它会等待主线程,一旦它可以被执行了才会被执行。当然了,我们也可以通过commitNow方法来马上触发事务,不过需要说明的是commitNow是和addToBackStack不兼容的,也就是说一旦你调用了commitNow方法就不能再使用返回栈了。还有一种方法就是调用executePendingTransactions方法,这个方法会执行所有被挂起的事务。

触发事务可能会引起Fragment的生命周期的变化,具体来说,当一个Fragment实例被执行add操作后,它会进入到STARED状态之中去。

通过事务我们还可以限制Fragment的生命周期,调用setMaxLifecycle方法可以为Fragment设置最大的生命周期,所谓的大和小就是靠近运行状态(Resume)的距离,距离运行状态越近生命周期越大。

Fragment的生命周期

接下来我们要谈到的是Fragment的生命周期,每一个Fragment都有其生命周期。Fragment实现了LifecycleOwner接口,说明Fragment也可以使用Lifecycle进行检测。实际上,Activity的LifecycleOwner状态的变化也是通过一个特殊的Fragment来进行跟踪的。除了使用Lifecycler之外,Fragment与Activity一样本身就带有关于生命周期的回调方法。

还需要说明的是Fragment的视图也单独有一个Lifecycle,它独立于Fragment的Lifecycle的,Fragment会为其视图维护一个LifecycleOwner,我们可以通过 getViewLifecycleOwner() 或 getViewLifecycleOwnerLiveData()进行访问。
在这里插入图片描述

生命周期之下的Fragment和Fragment管理器

具体来说Fragment的生命周期是由其FragmentManager所管理的,在实例化Fragment之后,它会从INITIALIZED状态开始,并且将其添加进入FragmentManager之中,FragmentManager负责确定ragment应该是处于哪个状态的。而且FragmentManager还会负责Fragment与其宿主Activity的附加和分离。将 Fragment 添加到 FragmentManager 并附加到其宿主 Activity 后,系统将调用 onAttach() 回调。此时,该 Fragment 处于活跃状态,FragmentManager 管理其生命周期状态。此时,findFragmentById() 等 FragmentManager 方法会返回此 Fragment。

在发生任何生命周期状态变更之前,系统都始终会调用 onAttach()在发生生命周期状态变更之后,系统始终都会调用 onDetach()

当Fragment被从FragmentManager之中移除并被分离之后会被触发其onDetach()方法,说明该Fragment已经不再处于活跃状态,并且我们无法通过findFragmentById()检索到。

Fragment生命周期状态与回调

在确定 Fragment 的生命周期状态时,FragmentManager 会考虑以下方面:

  • Fragment 的状态极限由其 FragmentManager 确定。Fragment 不能超过其 FragmentManager 的状态。
  • 作为 FragmentTransaction 的一部分,您可以使用 setMaxLifecycle() 在 Fragment 上设置生命周期状态极限。
  • Fragment 的生命周期状态绝对不能超过其父级。例如,父 Fragment 或 Activity 必须在其子 Fragment 之前启动。同样,子 Fragment 必须在其父 Fragment 或 Activity 之前停止。

这整个规则是很合理的,当然只有先启动了父Fragment才能启动子Fragment,下面便搬出Fragment生命周期转变的图,可以看到Fragment的生命周期和它的View的生命周期是不一样的
在这里插入图片描述
在Fragment发生状态改变的过程中系统会首先调用其新状态关联的生命周期回调,然后才会向Lifecycle发送Event事件触发Lifecycle框架下的回调方法。如果Fragment已经实例化的话,Fragment 的视图 Lifecycle 也会紧随其后向观察者发出此事件。

当Fragment到达了CREATED状态时就说明它已经被添加到了FragmentManager之中,并且已经调用了onAttach方法了。强烈建议将生命周期感知型组件与 Fragment 的 STARTED 状态相关联,因为该状态可确保 Fragment 的视图(如已创建)可用,并且可确保在 Fragment 的子 FragmentManager 上安全地执行 FragmentTransaction。如果 Fragment 的视图为非 null,在 Fragment 的 Lifecycle 转为 STARTED 后,Fragment 的视图 Lifecycle 会立即转为 STARTED。

当 Fragment 转为 STARTED 时,系统会调用 onStart() 回调。

Fragment 不再可见后,Fragment 及其视图的 Lifecycle 将转为 CREATED 状态,并向其观察者发出 ON_STOP 事件。不仅停止父 Activity 或 Fragment 会触发该状态转换,而且父 Activity 或 Fragment 保存状态也会触发该状态转换。此行为可保证在保存 Fragment 的状态之前调用 ON_STOP 事件。这使得 ON_STOP 事件成为能够安全地在子 FragmentManager 上执行 FragmentTransaction 的最后一个时间点。

如图所示,onStop() 回调与使用 onSaveInstanceState() 保存状态之间的顺序因 API 级别而异。对于 API 28 之前的所有 API 级别,在 onStop() 之前调用 onSaveInstanceState()。对于 API 28 及更高级别,调用顺序正好相反。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1034867.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【软件测试】测试中的风险有哪些?

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程,刷完面试就稳了,你也可以当高薪软件测试工程师(自动化测试) ​那么到底都有哪些风险要注意呢?如何解决呢?另外这些风险如何在计划中写明呢,不会写“张三…

汇编语言课程设计1 代码 优化版

assume cs:codesgstacksg segmentdw 16 dup(0) stacksg endsdatasg segmentdb 1975,1976,1977,1978,1979,1980,1981,1982,1983db 1984,1985,1986,1987,1988,1989,1990,1991,1992db 1993,1994,1995;以上是表示21年的21个字符串dd 16,22,382,1356,2390,8000,16000,24286,50065,97…

基于Java的酒店管理系统设计与实现(源码+lw+部署文档+讲解等)

前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…

文件-计算平均分

任务描述 本关任务:假设有若干学生,每个学生有3门功课,从键盘上输入学生有关信息(学号、姓名、成绩),并计算其平均成绩,将原有数据和平均分保存在磁盘文件record中。具体要求如下: 学生有关信…

【计算机毕业设计】基于SpringBoot+Vue大学生心理健康管理系统的开发与实现

博主主页:一季春秋博主简介:专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发,远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容:毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题…

计算机图形学中的几何光学

文章目录 前言一、图形学中的光学二、光照模型1、经验型(简单)2、物理型(复杂) 前言 在学习Shader光照之前了解一下计算机图形学 一、图形学中的光学 镜面反射的效果例子:物体表面高光 慢反射的效果的例子&#xff1a…

Python中获取主机名和IP地址的方法

在Python中,可以通过socket模块中gethostname()、getfqdn()和gethostbyname()方法获取本地和远程主机名和IP地址。 1 获取本地和远程主机名 1.1 获取本地主机名 可以通过gethostname()方法获取本地主机名,也就是本机的主机名,代码如下所示…

智能电力运维系统:数字化转型在电力行业的关键应用

随着信息技术、人工智能等的飞速发展,数字化改造已成为各行各业的重要发展趋势。在电力行业中,智能电力运维系统是数字化转型的关键应用之一。 力安科技智能电力运维系统是一种集自动化、智能化、云计算、物联网等先进技术于一体的电力运维管理解决方…

JS-ECharts-前端图表 多层级联合饼图、柱状堆叠图、柱/线组合图、趋势图、自定义中线、平均线、气泡备注点

本篇博客背景为JavaScript。在ECharts在线编码快速上手,绘制相关前端可视化图表。 ECharts官网:https://echarts.apache.org/zh/index.html 其他的一些推荐: AntV:https://antv.vision/zh chartcube:https://chartcub…

RocketMQ高性能核心原理与源码架构剖析(下)

四、融汇贯通阶段 开始梳理⼀些⽐较完整,⽐较复杂的完整业务线。 8 、消息持久化设计 1 、 RocketMQ 的持久化⽂件结构 消息持久化也就是将内存中的消息写⼊到本地磁盘的过程。⽽磁盘 IO 操作通常是⼀个很耗性能,很慢的操作,所以&#xf…

图像处理与计算机视觉--第三章-颜色与纹理分析-6问

图像处理与计算机视觉--第三章-颜色与纹理分析-6问 1.哪些因素决定物体颜色的感知? 对于物体颜色的感知,主要取决于以下三个因素: 1.照射到物体表面光波长的分布 2.物体表面如何反射照射光 3.传感器或者视觉细胞的敏感性 除了上述的三个因素之外&#xff0c…

nuc980学习笔记7-设置开机自启动

测试条件,nuc980开发板。 一、开机启动脚本 为什么需要开机自启动脚本?我们编写完程序之后,下载到开发板,往往需要程序开机自行启动,为了实现开机自启动,则需要编写相关的脚本。 二、设置开机启动的步骤 开…

2009-2022年上市公司华证 ESG数据

2009-2022年华证 ESG数据(年度) 1、时间:2009-2022年 2、范围:沪深A股上市公司 指标:证券简称、证券代码、华证ESG评级 2009-2022年华证ESG数据(季度) 1、时间:2009/03/31---20…

在React中,什么是组件的状态(state)?如何更新组件的状态?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 创建和初始化状态⭐ 更新状态⭐ 注意事项⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前…

力扣-228.汇总区间

AC Code 自己做出来的&#xff0c;代码写的很烂&#xff0c;但是也浅浅记录一下叭&#xff0c;下面有看答案思路写出来的双指针代码 class Solution { public:vector<string> summaryRanges(vector<int>& nums) {vector<string> ans;int n nums.size();…

Docker部署ElasticSearch数据库+analysis-ik分词器插件

文章目录 一、部署ElasticSearch数据库二、添加分词器插件(analysis-ik)三、测试ElasticSearch数据库analysis-ik分词器插件 一、部署ElasticSearch数据库 1、准备工作 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.6 Pwd"/data/software/elasticse…

csa从初阶到大牛(练习题2-查询)

新建2个文件d1.txt d2.txt ,使用vim打开d1.txt 输入“Hello World”字符串,将b1.txt 硬链接到b2.txt &#xff0c;查看2个文件的硬连接数 # 新建文件d1.txt和d2.txt touch d1.txt d2.txt# 使用vim编辑d1.txt并输入文本"Hello World" vim d1.txt# 创建硬链接b2.…

红黑树Java实现

文章目录 红黑树1. 概念性质2. 红黑树节点定义3. 红黑树的插入情况1情况2情况3其它细节问题插入代码实现 4. 红黑树的验证5.性能分析 红黑树 1. 概念性质 红黑树也是一种二插搜索树&#xff0c;每一个节点上比普通二插搜索树都增加了一个存储位置表示节点的颜色&#xff0c;可…

【lesson10】进程状态

文章目录 认识进程状态新建运行阻塞挂起 Linux具体的进程状态RSDtTXZ是什么为什么 认识进程状态 上面就是各种进程状态&#xff0c;上面都是理论进程状态理论进程状态放在哪个操作系统中都是正确的&#xff0c;但是具体的操作系统实现可能又会有所不同。 下面我们来理解进程状态…

SurroundOcc:用于自动驾驶的多摄像头3D占用网格预测

文章&#xff1a;SurroundOcc: Multi-Camera 3D Occupancy Prediction for Autonomous Driving 作者&#xff1a;Yi Wei, Linqing Zhao, Wenzhao Zheng, Zheng Zhu , Jie Zhou, Jiwen Lu 编辑&#xff1a;点云PCL 代码&#xff1a;https://github.com/weiyithu/SurroundOcc.git…