簡體   English   中英

視圖何時附加和分離?

[英]When are views attached and detached?

此問題與如何檢測視圖是否已附加或分離無關

一般情況下,何時附加或分離視圖? 這有生命周期圖嗎?

為了澄清,我正在尋找以下內容的答案:活動發送到后台,不透明視圖放在頂部,可見性設置為GONE ,查看膨脹,父級分離等等。這不是一個詳盡的列表 - 我只是想了解在一個基本層面上,如何附加和分離觀點。

更新我想要獲得的更多示例:

碎片與活動怎么樣?
嵌套視圖怎么樣 - 附加/分離視圖的順序是什么(parent-> child或child-> parent)?
視圖是在附加之前還是之后測量的?
如何手動將addView()用於ViewGroup?

編輯:摘要:

  • 對於“活動”,視圖附加在setContentView() 視圖在onDestroy()中分離,或者在使用不同視圖調用setContentView()時分離。
  • 對於片段,視圖onViewCreated()完成后onViewCreated() ,並在onDestroyView()完成后分離。
  • 對於ViewGroups,視圖附加在addView()並在removeView()分離
  • setVisibility()不會影響視圖的附加狀態

從官方文檔:

活動是用戶可以做的單一,專注的事情。 幾乎所有活動都與用戶互動......

需要注意的第一件事是,與布局相關聯的活動不是必須的。 您可以擁有一個沒有UI的活動(因此沒有View)。 Android甚至為此指定了無UI主題。

轉到您的問題 - 在您調用setContentView(view)時,View會附加到Activity。 這通常在onCreate()方法中調用。 你通常在onCreate()方法中使用它的原因是因為大多數初始化都是在那里完成的。 如果視圖未被誇大並附加到活動,您如何初始化您的小部件? 因此,如果您有一個視圖,那么幾乎不變的最終會在所有其他初始化之前調用onCreate()方法中的setContentView()。

但這是否意味着視圖(如果存在)必須僅在onCreate()方法中與活動相關聯?

要回答這個問題,讓我們看看Activity的生命周期是什么樣的。 你啟動你的應用程序:

onCreate() - > onStart() - > onResume()//它們被連續調用

您現在所處的階段是所有窗口小部件已初始化的位置。

那么為什么不在onResume()中膨脹和附加活動並在那里進行所有初始化?

當然,你可以。 但想象一下當對話框(部分不透明的視圖)出現時會發生什么? 該活動現已部分涵蓋,並在后台。 調用onPause()方法。 此時布局仍附加到Activity。 你采取了一些行動並解雇了對話框。 onResume()被調用。 布局將再次膨脹。 所有的初始化都會再次發生,你會失去你的狀態。 即使你沒有太多的初始化方法,你仍然可以通過再次調用onCreate()來進行相當昂貴的調用。 並且您希望在資源有限的移動設備中避免這種情況。

當不透明視圖出現並且活動現在在后台但仍在運行時(如來電或打開其他活動)會發生什么?

現在發生以下回調:

onPause() - > onStop()

當您返回原始活動時

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

出於與onPause()中提到的相同的原因,您不希望在此處膨脹和附加布局。

但是當Activity在后台時,布局本身會發生什么。 布局是否仍然附加?

是的,非常重要。 如果出現另一個使用與原始活動相同布局的活動,則新活動具有自己的布局,並且不會共享布局。

如果用戶通過按“返回”按鈕終止活動會發生什么?

假設未覆蓋onBackPressed()方法以實現自定義行為(在這種情況下,它可用於抓取),則調用onDestroy()並銷毀活動,並且不再有與之關聯的View。

當活動在后台並且Android GC決定銷毀活動並回收資源時會發生什么?

根據文檔中的活動生命周期,將調用onDestroy()。 但是不能保證這一點。 此時,活動及其關聯視圖只是垃圾收集而且沒有連接。下次啟動應用程序時,onCreate()將像往常一樣調用,您只需從頭開始。

旋轉設備時會發生什么?

Android的工作方式是實際銷毀當前活動並再次膨脹新布局並再次從onCreate()方法開始。 所以技術上發生的是:

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

因此,在橫向模式下甚至可以使用不同的布局和視圖。

編輯:添加活動,片段和視圖之間的關系片段表示屏幕上的一部分(或行為)。 可以使片段占據整個屏幕,也可以在活動中包含多個片段。 片段有自己的生命周期,但它與宿主活動的生命周期緊密相關(超出了本答案的范圍)。 由於我們專門討論意見,我將把這個答案限制在兩種感興趣的方法中:

  • onCreateView()
  • onViewCreated()

按以下順序調用方法:

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

您在onCreateView()中執行實際布局膨脹,然后在onViewCreated()方法中執行初始化。 Android使用onCreateView()方法的結果來擴展視圖。

那么什么時候片段是由活動創建的?

有兩種顯示片段的方法 - 一種是將它們放在活動的xml布局中(就像任何常規窗口小部件而不是窗口小部件名稱一樣,您將使用片段類的完全限定的包名稱)或者您可以以編程方式使用FragmentManager進行添加(這是首選方法)。

如果您在xml布局中定義片段,則應該知道無法以編程方式刪除片段。 很難修改它並將該屏幕空間重用於其他片段。 同樣在這種情況下,視圖被附加並綁定到活動。 在這種情況下,您將在活動的onCreate()方法中膨脹Activity的xml布局。 所以現在,流程看起來像:

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

因此,首先在創建活動的onStart()方法之前實例化片段視圖並將其附加到片段。

如果以編程方式添加片段,如果在onCreate()方法中添加片段,則它遵循相同的流程。 它可以在任何地方開始。 您只需在適當的位置替換活動中片段的生命周期。 以編程方式添加片段時,在片段托管在活動中時,視圖將附加到活動。 從活動中刪除片段時,將調用onDetach()並且視圖不再是Activity的一部分。 可以釋放片段占用的資源。

嵌套視圖,嵌套片段等怎么樣?

在嵌套視圖中,如同另一個布局容器中的一個布局容器,父容器的規則適用於直接子容器。 始終首先初始化父級。 因此,對於LinearLayout中的窗口小部件,首先構造父LinearLayout,然后緊跟子項。 在摧毀這些觀點時,一切都在父母不再存在時發生。 我還沒有讀過關於可能發生這種情況的訂單的任何文件。 Android GC可能有規則,但我不確定它們是否記錄在任何地方。

你也可以有嵌套的片段 - 在這種情況下,父片段在子片段之前被初始化(並且它有意義嗎?)。 當父母片段不再存在時,孩子也將不復存在。 沒有父母,孩子不能存在,但是你可以讓父母沒有孩子。

嵌套視圖的底線是,一旦父視圖被銷毀,它就會立即使用子視圖。

視圖是在附加之前還是之后測量的?

視圖在附加后進行測量。 調用getMeausredWidth()或getMeasuredHeight()將在此之前返回零。 但你可以做的是在附加之前直接在視圖上調用neasure()並傳遞MeasureSpecs(我建議你在官方文檔中閱讀更多內容)來設置一些約束。 但是這個選項並不是萬無一失的,因為它依賴於父ViewGroup強制執行它自己的約束,這些約束具有更高的優先級。 要簡單回答您的問題,請在附加后測量視圖。

如何使用addView()手動將視圖添加到ViewGroup?

這與嵌套視圖完全相同。 子項僅在添加時才存在,並且由用戶控制。 在布局xml中定義的嵌套視圖中,子項在其父項之后立即膨脹。 這里的控制更多地掌握在用戶手中。 在這種情況下,父視圖被銷毀時,它會帶有子視圖。

作為最后一點,我還想提一下,你不應該為視圖使用靜態句柄,因為這會導致很多令人頭疼的視圖被刪除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM