视图何时附加和分离?

2024-01-07

这个问题是not关于如何检测视图是否已附加或分离。

一般来说,什么时候附加或分离视图?有这方面的生命周期图吗?

为了澄清,我正在寻找以下情况下发生的情况的答案:活动发送到背景,不透明视图放置在顶部,可见性设置为GONE、视图膨胀、父级分离等。这不是一个详尽的列表 - 我只是想从根本上了解视图的附加和分离是如何工作的。

更新更多我想要了解的示例:

片段与活动怎么样?
嵌套视图怎么样 - 视图附加/分离的顺序是什么(父->子或子->父)?
视图是在附加之前还是之后测量的?
手动使用 addView() 到 ViewGroup 怎么样?

编辑:总结:

  • 对于活动,视图附在setContentView()。视图分离于onDestroy()或当setContentView()被称为不同的观点。
  • 对于片段,附有视图after onViewCreated()完成 http://developer.android.com/reference/android/app/Fragment.html#onViewCreated%28android.view.View,%20android.os.Bundle%29,并在之后分离onDestroyView()完成。
  • 对于 ViewGroups,视图附加在addView()并分离于removeView()
  • setVisibility()不影响视图的附加状态

来自官方文档:

活动是用户可以做的单一的、集中的事情。几乎 所有活动都与用户交互...

首先需要注意的是,活动不一定要与布局关联。您可以拥有一个没有 UI(因此没有视图)的 Activity。 Android 甚至为此指定了一个无 UI 主题。

继续你的问题 - 当你调用 setContentView(view) 时,视图会附加到活动。这通常在 onCreate() 方法中调用。通常在 onCreate() 方法中使用它的原因是因为大部分初始化都是在那里完成的。如果视图尚未膨胀并附加到 Activity,您如何初始化您的小部件?因此,如果您有一个视图,您几乎总是会在所有其他初始化之前在 onCreate() 方法中调用 setContentView() 。

但这是否意味着视图(如果存在)必须与 活动仅在 onCreate() 方法中?

为了回答这个问题,让我们看看 Activity 的生命周期是什么样的。您启动您的应用程序:

onCreate() -> onStart() -> onResume() // 它们被连续调用

您现在所处的阶段是所有小部件都已初始化的阶段。

那么为什么不在 onResume() 中膨胀并附加 Activity 并执行所有操作 那里有初始化?

当然,你可以。但想象一下当对话发生时会发生什么(部分不透明视图)出现?该活动现在已被部分覆盖并位于后台。调用 onPause() 方法。此时布局仍然附加到 Activity。您采取一些操作并关闭该对话框。 onResume() 被调用。布局将再次膨胀。所有的初始化都会再次发生,你会失去你的状态。即使您没有太多的初始化方式,您仍然会通过再次调用 onCreate() 来进行相当昂贵的调用。您希望在资源有限的移动设备中避免这种情况。

当出现不透明视图并且 Activity 现在处于状态时会发生什么 后台但仍在运行(例如来电或打开另一个活动)?

现在发生以下回调:

onPause() -> onStop()

当您返回原来的活动时

onRestart() -> onStart() -> onResume()

出于与我在 onPause() 中提到的相同原因,您不想在此处膨胀并附加布局。

但是当 Activity 位于布局中时,布局本身会发生什么? 背景。布局还在吗?

是的,确实如此。如果出现另一个使用与原始活动相同布局的活动,则新活动有自己的布局,并且不存在布局共享。

如果用户按“后退”终止活动会发生什么 按钮?

假设 onBackPressed() 方法没有被重写以实现自定义行为(在这种情况下,它是可以获取的),则调用 onDestroy() 并且活动被销毁,并且不再有与之关联的视图。

当 Activity 在后台且 Android GC 时会发生什么 决定销毁活动并回收资源?

根据文档中的活动生命周期,将调用 onDestroy()。但这并不能保证。此时,该 Activity 及其关联的视图只是被垃圾收集,并且没有连接。下次启动应用程序时, onCreate() 将像往常一样被调用,您只需从头开始即可。

当我旋转设备时会发生什么?

Android 的工作方式是实际销毁当前 Activity 并再次膨胀新布局,并再次从 onCreate() 方法开始。所以技术上发生的事情是:

onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onResume()

因此,您甚至可以在横向模式下拥有不同的布局和视图。

编辑:添加了活动、片段和视图之间的关系片段代表屏幕上的一部分(或行为)。可以使片段占据整个屏幕,也可以在一个活动中拥有多个片段。片段有自己的生命周期,但它与宿主活动的生命周期密切相关(并且超出了本答案的范围)。由于我们专门讨论视图,因此我将这个答案限制为两种感兴趣的方法:

  • onCreateView()
  • onViewCreated()

这些方法按以下顺序调用:

onAttach() -> onCreate() -> onCreateView() -> onViewCreated()

您在 onCreateView() 中执行实际的布局膨胀,然后在 onViewCreated() 方法中执行初始化。 Android 使用 onCreateView() 方法的结果来膨胀视图。

那么 Activity 最初是什么时候创建 Fragment 的呢?

有两种显示片段的方法 - 一种是将它们放在活动的 xml 布局中(就像任何常规小部件一样,您将使用片段类的完全限定包名称,而不是小部件名称)或者您可以以编程方式使用 FragmentManager 进行添加(这是首选方法)。

如果您在 xml 布局中定义片段,您应该知道无法以编程方式删除该片段。很难修改它并为其他片段重用该屏幕空间。同样在这种情况下,视图附加并绑定到活动。在这种情况下,您将在 Activity 的 onCreate() 方法中扩充 Activity 的 xml 布局。现在,流程将类似于:

onCreate() [活动] -> onAttach() [片段] -> onCreate() [片段] -> onCreateView() [片段] -> onViewCreated() [片段] -> onStart() [活动] -> onResume() [活动] -> onActivityCreated() [片段]

因此,在创建活动的 onStart() 方法之前,首先实例化片段视图并将其附加到片段。

如果以编程方式添加片段,或者在 onCreate() 方法中添加片段,则它遵循相同的流程。它可以在任何地方启动。您只需将片段的生命周期替换为活动中适当的位置即可。当您以编程方式添加片段时,当片段托管在活动中时,视图将附加到活动。当片段从 Activity 中删除时,将调用 onDetach(),并且视图不再是 Activity 的一部分。分片占用的资源可以被释放。

嵌套视图、嵌套片段等怎么样?

在嵌套视图中,就像一个布局容器位于另一个布局容器中一样,父容器的规则适用于直接子容器。父级总是首先被初始化。因此,对于 LinearLayout 内的小部件,首先构造父 LinearLayout,紧接着构造子 LinearLayout。当摧毁这样的观点时,当父母不复存在时,一切都会消失。我还没有读过任何关于这种情况可能发生的顺序的文档。 Android GC 可能有规则,但我不确定它们是否在任何地方都有记录。

您也可以有嵌套片段 - 在这种情况下,父片段在子片段初始化之前被初始化(这很有意义,不是吗?)。当父片段不复存在时,子片段也将不复存在。没有父母,孩子就不能存在,但没有孩子,你可以有父母。

嵌套视图的底线是一旦父视图被 销毁后,它会立即带走子视图。

视图是在附加之前还是之后测量的?

视图是在附加后进行测量的。在此之前调用 getMeausredWidth() 或 getMeasuredHeight() 将返回零。但是您可以做的是在附加视图之前直接在视图上调用 neasure() 并传递 MeasureSpecs (我建议您在官方文档中阅读更多相关内容)来设置一些约束。但这个选项并不是万无一失的,因为它依赖于父 ViewGroup 强制执行它自己的约束,而这些约束具有更高的优先级。为了简单地回答您的问题,视图是在附加后进行测量的。

使用 addView() 手动将视图添加到 ViewGroup 怎么样?

这与嵌套视图完全相同。子项仅在添加时才存在,并且由用户控制。在布局 xml 中定义的嵌套视图中,子视图在其父视图之后立即膨胀。在这里,控制权更多地掌握在用户手中。当本例中的父视图被销毁时,子视图也会随之被销毁。

最后一点,我还想提一下,您不应该对视图使用静态句柄,因为这会导致视图拆除时出现很多麻烦。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

视图何时附加和分离? 的相关文章

随机推荐

  • aws codedeploy 部署期间的 git 修订版

    我正在使用 AWS CodeDeploy 服务运行一些测试 并设法从 github 部署我的应用程序 到目前为止一切顺利 但现在我需要部署在 AfterInstall 挂钩中的 git 修订版 有没有办法获得 git 版本 已经查看了部署存
  • 内部带有 nohup 的脚本无法正确退出

    我们有一些脚本可以使用 nohup 进行一些处理并在后台触发作业 当我们从 Oracle OEM 调度此脚本 或者它可以是任何调度程序作业 时 我看到以下错误并显示状态为失败 但脚本实际上完成时没有问题 使用nohup启动备份地面作业时如何
  • 在Python/Pandas中将dtype“object”的所有列转换为“float”

    我想将数据框中的所有 对象 类型列转换为另一种数据类型 浮点数 而不需要对列名称进行硬编码 我能够从其他似乎有效的答案中拼凑出一些代码 但我觉得必须有一种更简单的方法来做到这一点 Creating isolating columns of
  • 使用 Selenium Python chromeDriver 向下滚动到结束页面

    请帮忙 我想向下滚动到袋子的末尾 但它停止了 我尝试的代码在这里 browser webdriver Chrome browser get url button browser find element by tag name html o
  • Slick:选项列过滤

    我想做这样的事情 这是一个虚构的例子 以简化我的实际问题 def findByGender isMale Option Boolean People filter row gt row name isNotNull isMale match
  • 如何禁用编译器和 JVM 优化?

    我有这段正在测试的代码Calendar getInstance getTimeInMillis vs System currentTimeMilli long before getTimeInMilli for int i 0 i lt T
  • 从 java 代码启动和停止 Tomcat

    基于我在 Stackoverflow 和互联网上其他页面上看到的代码 我创建了一种方法来停止和启动 tomcat 此时我将在系统中运行一个进程 因为我需要清理操作系统中的内存 我使用System gc 但仍然不足以释放内存 这是代码 全球声
  • 将 UTF-8 转换为 base64 字符串

    我正在尝试转换UTF 8 to base64 string 示例 我有 abcdef UTF 8 它实际上是一个 代表 base64细绳 如何检索 abcdef base64字符串 请注意 我不想要来自的 abcdef 翻译 UTF 8 我
  • Java 8:Lambda 函数和通用通配符

    我有以下课程 class Book implement Borrowable Override public String toString Function
  • NSOperationQueue 在 iPhone 上不重用线程

    我正在使用 iPhone SDK 3 1 2 以下代码显示 NSOperationQueue 不会为每个任务重用线程 该代码在 Snow Leopard 上没有任何问题 void applicationDidFinishLaunching
  • YouTube API - 检索超过 5000 个项目

    我只想获取所有我喜欢的视频 25k 项 据我的研究表明 通过 YouTube v3 API 是不可能实现这一点的 我已经发现多个问题 issue https stackoverflow com questions 56389215 how
  • 使用 jQuery 计算两个特定行之间的表行数

    table tr td Parent 1 td tr tr class child td Child 1 td tr tr class child td Child 2 td tr tr td Parent2 td tr table 如何使
  • 将VBA中的文件路径替换为用户名

    我有一个 Excel 文件 上面写有 VBA 它从我的计算机上的文件中提取信息 Excel 文件位于网络文件夹中 我希望网络上的其他用户也能使用它 但是 我已对 VBA 上的文件路径进行了硬编码 因此 每当其他用户打开它时 它都会查找不可用
  • 如何在应用程序域之间传递事件?

    我有两个应用程序域 一个父域创建子域 在子域中 有一个MarshalByRef对象 使用 NET Remoting 进行通信 在父域中运行的对象调用远程对象的包装器作为应用程序功能的一部分 public class ScanningTask
  • 这是什么意思? (谷歌地图 API)

    我在控制台中收到此错误消息 谁能解释为什么 并且页面正在正常运行 js key MyAPIKey v 3 exp libraries places drawing geometry 32 InvalidValueError not an i
  • 将用户 ID 添加到 PhoneGap 文件上传

    我想使用 PhoneGap API 上传照片 FileTransfer 对象基本上就是我想要的 因为我想上传照片 但我想包含一些有关用户的基本信息 例如他们的用户 ID 以便我可以将其存储为他们的 我的代码如下 这基本上来自PhoneGap
  • ifstream 未打开文件

    在此函数中 我试图打开一个文件 其中包含一组我想分配给矩阵数组的字符 但是每当我运行此程序时 控制台都会显示一条错误 指出该文件未打开 另一个问题 如果我将该文件添加到我的资源文件夹中 我如何指定访问该文件而不是硬盘驱动器根目录中的文件 i
  • Keras:如何在训练和测试阶段使用 dropout?

    是否可以在 Keras 的训练和测试阶段使用 dropout 就像这里描述的那样 https github com soumith ganhacks 17 use dropouts in g in both train and test p
  • Office.context.mailbox.displayNewMessageForm 在移动设备中不起作用

    我试图通过单击 Outlook Web 插件中的按钮来创建新的邮件表单 然后使用显示新消息表格 https learn microsoft com en gb office dev add ins reference objectmodel
  • 视图何时附加和分离?

    这个问题是not关于如何检测视图是否已附加或分离 一般来说 什么时候附加或分离视图 有这方面的生命周期图吗 为了澄清 我正在寻找以下情况下发生的情况的答案 活动发送到背景 不透明视图放置在顶部 可见性设置为GONE 视图膨胀 父级分离等 这