view有三大工作流程:測量肢专、布局、繪制焦辅,分別對應(yīng)著方法mesure博杖、layout、draw
ViewRoot和DecorView
ViewRoot對應(yīng)的類是ViewRootImpl類筷登,是連接WindowManager和DecorView的紐帶剃根,View的三大流程都是由ViewRoot來完成的,在Activity創(chuàng)建完成之后仆抵,會將DecorView添加到Window中跟继,同時創(chuàng)建啊ViewRootImpl對象,并將此對象與DecorView連接起來
View的繪制是從ViewRoot的PerformTraversals方法開始的镣丑,這個方法會依次調(diào)用performMeasure舔糖、performLayout、performDraw方法莺匠,這三個方法分別調(diào)用頂級View的measure金吗、layout、draw方法,在后面的這三個方法中又會分別調(diào)用onMeasuer摇庙、onLayout旱物、onDraw方法,在這三個方法中會對所有子元素進行measure卫袒、layout宵呛、draw,這時候就從父容器繪制流程傳遞到了子元素中去了
performDraw的傳遞過程是在draw方法中通過dispatchDraw方法來實現(xiàn)的
measure過程決定了view的寬高夕凝,通過getMeasuredWidth和getMeasuredHeight獲得測量后的寬高宝穗,getWidth、getHeight獲得最終寬高码秉,layout決定view的位置逮矛,Draw決定view的顯示
DecorView是頂級View,本質(zhì)是一個FrameLayout转砖,一般內(nèi)部包含一個線性布局(標(biāo)題欄+內(nèi)容欄)
MeasureSpec
MeasureSpec是一個32位int值须鼎,高2位代表SpecMode,低30位代表SpecSize,要受到父容器的影響
SpecMode有3類:UNSPECIFIED、EXACTLY府蔗、AT_MOST
- UNSPECIFIED:父容器不對View做任何限制
- EXACTLY:父容器檢測出View的大小晋控,View的最終大小為SpecSize
- AT_MOST:父容器指定了一個可用大小的SpecSize,View的大小不能超過這個值
MeasureSpec和LayoutParams
view的測量是系統(tǒng)通過MeasureSpec來實現(xiàn)的礁竞,我們給View設(shè)置LayoutParams后糖荒,系統(tǒng)會將LayoutParams在父容器的約束下轉(zhuǎn)化成對應(yīng)的MeasureSpec,然后根據(jù)這個MeasureSpec確定View的寬高
對于頂級DecorView模捂,MeasureSpec由窗口尺寸和其自身的LayoutParams決定捶朵,對于普通的View,MeasureSpec由父容器的MeasureSpec和自身的LayoutParams決定
View工作流程
主要指:測量狂男、布局综看、繪制
Measure過程
如果是View就通過measure方法完成測量,如果是ViewGoup完成自己測量過程外還要完成子元素的測量(調(diào)用所有子元素的measure方法)
view的measure方法是一個final類型岖食,子類不能重寫红碑,在這個方法中回去調(diào)用onMeasure方法
view的最終大小是在layout階段完成的
直接繼承View的控件需要重寫onMeasure方法并設(shè)置wrap_content時的自身大小
ViewGroup除了完成自己的measure還要遍歷子元素調(diào)用子元素的measure方法,ViewGoup是個抽象類泡垃,沒有重寫View的onMeasure方法析珊,提供了一個measureChildren方法
View的measure過程不是個activity的生命周期同步執(zhí)行的
獲取View寬高方法:
- 在onWindowFocusChanged方法里獲取
- 通過View.post方法
- 使用ViewTreeObserver的回調(diào)方法中
- 使用view.measure
Layout過程
當(dāng)ViewGroup確定位置后,在它的onLayout中會遍歷其子元素并調(diào)用其layout方法蔑穴,在layout方法中onLayout方法又會調(diào)用忠寻,layout方法確定其View的位置,onLayout確定其子元素的位置
draw過程
將View繪制在屏幕上存和,繪制過程:
- 繪制背景
- 繪制自己
- 繪制children
- 繪制裝飾
View繪制過程的傳遞是通過dispatchDraw來實現(xiàn)的奕剃,dispatchDraw會調(diào)用所有子元素的draw方法