- 控件大緻被分為兩類,ViewGroup控件和View控件。ViewGroup空間可以包含多個View控件,并管理其包含的View控件。
- 通過ViewGroup,整個界面上的控件形成一個樹形結構,也就是我們常說的控件樹,上層控件負責下層子控件的測量與繪制,并傳遞互動事件。
- 通常在Activity中使用findViewById()方法,就是在控件樹中以樹的深度優先周遊來查找對應元素。
- 在每棵控件樹的頂部,都有一個ViewParent對象,這就是整棵樹的控制核心,所有的互動管理事件都由它統一排程和配置設定,進而可以對整個視圖進行整體控制。View視圖樹如下圖所示。
通常情況下,在Activity中使用setContentView()方法來設定一個布局,在調用該方法後,布局内容才真正顯示出來。下面來看一下Android界面的架構圖,如下圖所示。
- 每個Activity都包含一個Window對象,在Android中Window對象通常由PhoneWindow來實作。
- PhoneWindow将一個DecorView設定為整個應用視窗的根View。
- DecorView作為視窗界面的頂層視圖,封裝了一些視窗操作的通用方法。
- 可以說,DecorView将要顯示的具體内容呈現在了PhoneWindow上,這裡面的所有View的監聽事件都通過WindowManagerService來進行接收,并通過Activity對象來回調相應的onClickListener。在顯示上,他将螢幕分為兩部分,一個是TitleView,另一個是ContentView。
- 看到這裡,大家一定看見了一個非常熟悉得布局----ContentView。它是一個ID為content的FrameLayout,activity_main.xml就是設定在這樣一個Framelayout裡。通過以上過程,我們可以建立起這樣一個标準視圖樹,如下圖所示。
- 上圖所示的視圖樹的第二層裝在了一個LinearLayout作為ViewGroup,這一層的布局結構會根據對應的參數設定不同的布局,如最常用的布局----上面顯示TitleBar,下面是Content這樣的布局,也就是圖3.3中所設定的布局。
- 而如果使用者通過設定requestWindowFeature(Window.FEATURE_NO_TITLE)來設定顯示全屏,視圖樹中的布局就隻有Content了,這就解釋了為什麼調用requestWindowFeature()方法一定要在setContentView()方法之前才能生效的原因。
- 不過這裡要注意的是,由于每個Android版本對UI的修改都比較多,上圖隻是比較粗略地顯示了視圖樹的結構。
- 而在代碼中,當程式在onCreat()方法中調用setContentView()方法後,ActivityManagerService會回調onResume()方法,此時系統才會把整個DecorView添加到PhoneWindow中,并讓其顯示出來,進而最終完成界面的繪制。
内容參考自:
Blankj