视图何时附加和分离?

时间:2015-03-12 22:16:50

标签: android android-view

这个问题关于如何检测视图是附加还是分离。

一般情况下,视图何时附加或分离?是否有生命周期图?

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

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

片段与活动如何?
嵌套视图怎么样 - 附加/分离视图的顺序是什么(parent-> child或child-> parent)?
视图是在附加之前还是之后测量的? 如何手动将addView()用于ViewGroup?

编辑:摘要:

  • 对于“活动”,视图附在setContentView()中。视图在onDestroy()中分离,或者在使用不同视图调用setContentView()时分离。
  • 对于片段,视图会附加after onViewCreated() finishes,并在onDestroyView()完成后分离。
  • 对于ViewGroups,视图附加在addView()中,并在removeView()
  • 中分离
  • setVisibility()不会影响视图的附加状态

1 个答案:

答案 0 :(得分:38)

来自官方文件:

  

活动是用户可以做的一件重点事。几乎   所有活动都与用户互动......

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

继续讨论您的问题 - 在您调用setContentView(view)时,View会附加到Activity。这通常在onCreate()方法中调用。你通常在onCreate()方法中使用它的原因是因为大多数初始化都是在那里完成的。如果视图未被夸大并附加到活动,您如何初始化您的小部件?因此,如果你有一个视图,你几乎不变,最终在你的onCreate()方法中调用setContentView(),然后再进行所有其他初始化。

  

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

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

  

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

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

  

那么为什么不在onResume()中充气并附加活动并完成所有操作   在那里初始化?

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

  

当一个不透明的视图出现并且Activity现在进入时会发生什么   背景但仍在运行(如来电或打开其他活动)?

现在发生以下回调:

  

onPause() - >的onStop()

当您返回原始活动时

  

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

出于与onPause()中提到的相同的原因,您不想在此处充气和附加布局。

  

但是当一个Activity进入时,布局本身会发生什么   背景。布局是否仍然附加?

是的,非常重要。如果出现了另一个使用与原始活动相同布局的活动,则新活动具有自己的布局,并且不会共享布局。

  

如果用户按Back键终止活动会发生什么   按钮?

假设未覆盖onBackPressed()方法以实现自定义行为(在这种情况下,它可用于抓取),则调用onDestroy()并销毁活动,并且不再有与之关联的View。

  

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

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

  

旋转设备时会发生什么?

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

  

onPause() - &gt; onStop() - &gt; onDestroy() - &gt; onCreate() - &gt; onStart() - &gt;   的onResume()

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

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

  
      
  • onCreateView()
  •   
  • onViewCreated()
  •   

按以下顺序调用方法:

  

onAttach() - &gt; onCreate() - &gt; onCreateView() - &gt; onViewCreated()

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

  

那么什么时候片段是由活动创建的呢?

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

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

  

onCreate()[活动] - &gt; onAttach()[片段] - &gt;的onCreate()   [片段] - &gt; onCreateView()[Fragment] - &gt; onViewCreated()[片段]    - &GT; onStart()[活动] - &gt; onResume()[活动] - &gt; onActivityCreated()[片段]

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

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

  

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

在嵌套视图中,就像一个布局容器在另一个布局容器中一样,父容器的规则适用于直接子容器。始终首先初始化父级。因此,对于LinearLayout中的窗口小部件,首先构造父LinearLayout,然后紧跟子项。在摧毁这些观点时,一切都在父母不再存在时发生。我还没有读过关于可能发生这种情况的订单的任何文件。 Android GC可能有规则,但我不确定它们是否记录在任何地方。

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

  

嵌套视图的底线是父视图的底线   被摧毁,它立即带着孩子的视线。

     

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

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

  

如何使用addView()手动将视图添加到ViewGroup?

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

作为最后一点,我还想提到你不应该为视图使用静态句柄,因为这会导致很多令人头疼的视图被删除。