內(nèi)容是博主照著書敲出來(lái)的,博主碼字挺辛苦的,轉(zhuǎn)載請(qǐng)注明出處治拿,后序內(nèi)容陸續(xù)會(huì)碼出。
控件大致被分為兩類笆焰,ViewGroup控件和View控件劫谅。ViewGroup可以包含多個(gè)View并管理它們。通過(guò)ViewGroup仙辟,整個(gè)界面上的控件形成一個(gè)樹形結(jié)構(gòu)同波,也就是我們常說(shuō)的控件樹,上層控件負(fù)責(zé)下層子控件的測(cè)量與繪制叠国,并傳遞交互事件未檩。通常在Activity中使用findViewById()方法,就是在控件樹中以樹的深度優(yōu)先遍歷來(lái)查找對(duì)應(yīng)元素粟焊。在每棵控件樹的頂部冤狡,都有一個(gè)ViewParent對(duì)象,這就是整棵樹的控制核心项棠,所有的交互管理事件都由它統(tǒng)一調(diào)度和分配悲雳,從而可以對(duì)整個(gè)視圖進(jìn)行整體控制。View視圖樹如下圖所示香追。
通常情況下合瓢,在Activity中使用setContentView()方法來(lái)設(shè)置一個(gè)布局,在調(diào)用該方法后透典,布局內(nèi)容才真正顯示出來(lái)晴楔。下面來(lái)看一下Android界面的架構(gòu)圖顿苇,如下圖所示。
每個(gè)Activity都包含一個(gè)Window對(duì)象税弃,在Android中Window對(duì)象通常由PhoneWindow來(lái)實(shí)現(xiàn)纪岁。PhoneWindow將一個(gè)DecorView設(shè)置為整個(gè)應(yīng)用窗口的根View。DecorView作為窗口界面的頂層視圖则果,封裝了一些窗口操作的通用方法幔翰。可以說(shuō)西壮,DecorView將要顯示的具體內(nèi)容呈現(xiàn)在了PhoneWindow上遗增,這里面的所有View的監(jiān)聽事件都通過(guò)WindowManagerService來(lái)進(jìn)行接收,并通過(guò)Activity對(duì)象來(lái)回調(diào)相應(yīng)的onClickListener茸时。在顯示上贡定,他將屏幕分為兩部分,一個(gè)是TitleView可都,另一個(gè)是ContentView缓待。看到這里渠牲,大家一定看見了一個(gè)非常熟悉得布局----ContentView旋炒。它是一個(gè)ID為content的FrameLayout,activity_main.xml就是設(shè)置在這樣一個(gè)Framelayout里签杈。通過(guò)以上過(guò)程瘫镇,我們可以建立起這樣一個(gè)標(biāo)準(zhǔn)視圖樹,如下圖所示答姥。
上圖所示的視圖樹的第二層裝在了一個(gè)LinearLayout作為ViewGroup铣除,這一層的布局結(jié)構(gòu)會(huì)根據(jù)對(duì)應(yīng)的參數(shù)設(shè)置不同的布局,如最常用的布局----上面顯示TitleBar鹦付,下面是Content這樣的布局尚粘,也就是圖3.3中所設(shè)置的布局。而如果用戶通過(guò)設(shè)置requestWindowFeature(Window.FEATURE_NO_TITLE)來(lái)設(shè)置顯示全屏敲长,視圖樹中的布局就只有Content了郎嫁,這就解釋了為什么調(diào)用requestWindowFeature()方法一定要在setContentView()方法之前才能生效的原因。不過(guò)這里要注意的是祈噪,由于每個(gè)Android版本對(duì)UI的修改都比較多泽铛,上圖只是比較粗略地顯示了視圖樹的結(jié)構(gòu)。
而在代碼中辑鲤,當(dāng)程序在onCreat()方法中調(diào)用setContentView()方法后盔腔,ActivityManagerService會(huì)回調(diào)onResume()方法,此時(shí)系統(tǒng)才會(huì)把整個(gè)DecorView添加到PhoneWindow中,并讓其顯示出來(lái)铲觉,從而最終完成界面的繪制澈蝙。
原文地址Android控件架構(gòu)(Android群英傳)
我的自媒體博客blankj小站吓坚,歡迎來(lái)逛逛撵幽。