UI繪制流程

一:View是如何被添加到屏幕窗口的命锄。

打開Activity,在oncreat()方法里面镰吆,調(diào)用了setContentView()方法护盈,方法參數(shù)傳入布局文件。調(diào)用流程:??

setContentView()-->getWindow().setContentView()【getWindow是Window類中的方法闲先,Window繼承了抽象的PhoneWindow】--->實(shí)際調(diào)用了PhoneWindow中的setContentView()方法-->調(diào)用instalDecor()
方法状土,在此方法中首先調(diào)用generateDecor()方法,創(chuàng)建DecorView對象伺糠,其次調(diào)用了generateLayout()方法首先根據(jù)features不同初始化不同的layoutResource(基礎(chǔ)容器)-->通過onResourceLoaded()方法把layoutResource進(jìn)行解析蒙谓,并添加到DecorView容器上。然后在generateLayout()方法中通過findViewByID找到R.id.conent的容器退盯,該容器為FrameLayout彼乌,把通過setContentView()方法傳遞進(jìn)入的布局文件解析到FrameLayout容器中泻肯。

總結(jié):首先系統(tǒng)會創(chuàng)建一個頂層的容器DecorView渊迁,DecorView是ViewGroup繼承FrameLayout慰照,是PhoneWindow持有的一個實(shí)例,DecorView是所有應(yīng)用程序的頂層View琉朽,在系統(tǒng)內(nèi)部進(jìn)行初始化毒租,當(dāng)DecorView完成初始化之后系統(tǒng)不根據(jù)當(dāng)前應(yīng)用程序的主題特性,加載一個基礎(chǔ)容器箱叁,例如:no_action_bar,dark_action_bar墅垮。不同的主題加載的基礎(chǔ)容器不同,但基礎(chǔ)容器都存在R.id.content的FrameLayout的容器耕漱,我們開發(fā)者通過setContentView設(shè)置的布局文件(xml文件)就是通過解析之后加載到FrameLayout中的算色。


二:View的繪制流程

1:繪制入口

ActivitytThread.handleResumeActivity()--->WindowManagerImpl.addView(decorView,layoutParams)-->WindowManagerGlobal.addView(),此方法會創(chuàng)建出ViewRootImpl對象

2:繪制類及方法

ViewRootImpl.setView(decorView,layoutParams,parentView)將decorView與布局屬性,布局進(jìn)行關(guān)聯(lián)--->ViewRootImpl.requestLayout()--->ViewRootImpl.scheduleTraversals()--->子線程調(diào)用doTraversals()--->performTraversals()螟够,次方法是真正繪制的方法灾梦。

3:繪制三大步驟

測量:ViewRootImpl.performMeasure();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 布局:ViewRootImpl.performLayout();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 繪制:ViewRootImpl.performDraw();

總結(jié):當(dāng)Activity創(chuàng)建之后,在Activty的handlResumeActivity()方法中通過VM調(diào)用了addView方法妓笙,VM找到實(shí)現(xiàn)類WindowManagerImpl若河,調(diào)用addView()方法,addView第一個參數(shù)是頂層的DecorView寞宫,第二個參數(shù)是布局屬性萧福。接著調(diào)用WindowManagerGloabl.addView()方法,再次方法中會創(chuàng)建ViewRootImpl對象辈赋,調(diào)用setView()方法鲫忍,將DecorView,布局屬性钥屈,布局進(jìn)行關(guān)聯(lián)饲窿,關(guān)聯(lián)成功后ViewRootImpl準(zhǔn)備繪制,調(diào)用了ViewRootImpl的requestLyaout()方法,然后調(diào)用了schedluTraversals(),在子線程調(diào)用了doTraversals()方法焕蹄,在調(diào)用了perFormTraversals(),次方法是真正真正繪制的方法逾雄。

4:詳細(xì)步驟(測量)

(1)View的測量包含兩部分模式+尺寸,被封裝到了MeasureSpec

? ? MeasureSpec:是一個32位int類型的值腻脏,前面2位是模式鸦泳,后面30位是尺寸。是View 的測量規(guī)格? ? ? ? ? ? ? ? ? view的測量 = specMode (模式) + specSize(尺寸)永品。

? ?makeMeasureSpec方法把模式和尺寸打包生成成MeasureSpec

???a:?3種測量模式做鹰。? MODE_SHIFT = 30 位? ? ? ?MODE_MASK =0x3 <<MODE_SHIFT

? ? UNSPECIFIED? ?0<<MODE_SHIFT? 父容器不對View做任何限制,一般系統(tǒng)使用鼎姐。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? EXACTLY? ? ? ? ? 1<<MODE_SHIFT? 父容器檢測view的大小钾麸,view的大小就是specSize 更振,布局屬性? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? layoutParams子控件match_parent 或者固定大小。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?AT_MOST? ? ? ? ?2<<MODE_SHIFT? 父容器指定一個可用大小specSize饭尝,view最大不能超過這個值肯腕,布? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 局屬性子控件 layoutParams為wrap_content

b:頂層View -------確定DecorView的MeasureSpec

?DecorView的MeasureSpec由窗口大小,自身的LayoutParsms決定钥平。

自身LayoutParsms.MATCH_PARENT:精確模式实撒,大小為窗口大小,模式為 EXACTLY.
自身LayoutParsms.WRAP_CONTENT:最大模式涉瘾,大小最大為窗口大小知态,模式為 AT_MOST.
固定大小:精確模式立叛,大小自身LayoutParsms的大小负敏,模式為 EXACTLY.



View測量
ViewGroup? ?mesure()---->onMeasure(測量子控件的寬高)--->setMeasureDimesion()-->setMeasureDimesionRaw(保存自己的寬高)

View? ? ?mesure()---->onMeasure()--->setMeasureDimesion()-->setMeasureDimesionRaw(保存自己的寬高)

View 的布局
ViewGroup? ?layout(來確定自己的位置,4個點(diǎn)左上右下)--->onLayout(進(jìn)行子View的布局)
View? ? ? ? ? ? ?layout(來確定自己的位置秘蛇,4個點(diǎn)左上右下)

View的繪制
ViewGroup
(1)繪制背景? drawBackGround(canvas)
(2)繪制自己? onDraw(canvas)
(3)繪制子View dispatchDraw(canvas)
(4)繪制前景其做,滾動條等裝飾 onDrawForeground(canvas)
View
(1)繪制背景? drawBackGround(canvas)
(2)繪制自己? onDraw(canvas)
(3)繪制子View dispatchDraw(canvas)
(4)繪制前景,滾動條等裝飾 onDrawForeground(canvas)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彤叉,一起剝皮案震驚了整個濱河市庶柿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秽浇,老刑警劉巖浮庐,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柬焕,居然都是意外死亡审残,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門斑举,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搅轿,“玉大人,你說我怎么就攤上這事富玷¤捣兀” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵赎懦,是天一觀的道長雀鹃。 經(jīng)常有香客問我,道長励两,這世上最難降的妖魔是什么黎茎? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮当悔,結(jié)果婚禮上傅瞻,老公的妹妹穿的比我還像新娘踢代。我一直安慰自己,他們只是感情好嗅骄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布胳挎。 她就那樣靜靜地躺著,像睡著了一般掸读。 火紅的嫁衣襯著肌膚如雪串远。 梳的紋絲不亂的頭發(fā)上宏多,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天儿惫,我揣著相機(jī)與錄音,去河邊找鬼伸但。 笑死肾请,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的更胖。 我是一名探鬼主播铛铁,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼却妨!你這毒婦竟也來了饵逐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤彪标,失蹤者是張志新(化名)和其女友劉穎倍权,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捞烟,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡薄声,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了题画。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片默辨。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖苍息,靈堂內(nèi)的尸體忽然破棺而出缩幸,到底是詐尸還是另有隱情,我是刑警寧澤竞思,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布表谊,位于F島的核電站,受9級特大地震影響衙四,放射性物質(zhì)發(fā)生泄漏铃肯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一传蹈、第九天 我趴在偏房一處隱蔽的房頂上張望押逼。 院中可真熱鬧步藕,春花似錦、人聲如沸挑格。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漂彤。三九已至雾消,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挫望,已是汗流浹背立润。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留媳板,地道東北人桑腮。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像蛉幸,于是被迫代替她去往敵國和親破讨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容