View繪制過程及原理

? ? ?View的繪制過程就是從ViewRoot的performTraversals方法開始的,它先后經(jīng)過measurelayout、draw三個過程才能最終將一個View繪制出來。分別對應(yīng)onMeasure()、onLayout()和onDraw()這三個方法。下面分別談一下這三個方法。

measure

? ? measure是用來測量view的寬和高。在measure方法中又會調(diào)用onMeasure方法,在onMeasure方法中會對所有的子元素進(jìn)行measure過程,這個時候measure流程就從父容器傳遞到子元素中了


measure()方法接收兩個參數(shù),widthMeasureSpec和heightMeasureSpec,這兩個值分別用于確定視圖的寬度和高度的測量規(guī)格。MeasureSpec代表一個32的int值,高2位代表SpecMode測量模式,低30位代表SpecSize測量規(guī)格大小。SpecMode 分為三類

? 1.EXACTLY(完全)

? ? 父容器完全決定view的大小,子view的大小被忽略,被限定在給定的邊界里。

? 2.AT_MOST(至多)

? ? 子view最多達(dá)到給定大小的值

? 3.UNSPECIFIED(未指定)

? ? 父容器不對view的大小做任何限制,子view可以得到任意想要的大小

? 在setMeasuredDimension()方法調(diào)用之后,我們才能使用getMeasuredWidth()和getMeasuredHeight()來獲取視圖測量出的寬高,以此之前調(diào)用這兩個方法得到的值都會是0。

layout

? layout方法是在measure方法結(jié)束后進(jìn)行,此時view的大小已經(jīng)測量好了。layout的作用是ViewGroup用來確定子元素的位置,當(dāng)ViewGroup的位置被確定后,它在onLayout中會遍歷所有的子元素并調(diào)用Layout方法,在layout方法中onLayout方法又會被調(diào)用。這樣一層一層的完成所有子View的布局過程。layout里面通過setFrame來確定View的四個頂點的位置,然后再layout中調(diào)用onLayout,這個方法用來確定子View的位置,起到一層層傳遞的作用。

draw

? draw方法是在layout方法結(jié)束后進(jìn)行,顧名思義,這里是繪制view的地方。draw主要分為6步。

? 1.繪制view的背景圖

? 2.如果要視圖顯示漸變框,開始準(zhǔn)備

? 3.調(diào)用onDraw()函數(shù),繪制視圖本身。在view中進(jìn)入onDraw()方法會發(fā)現(xiàn)是個空方法,因為每個子類視圖的內(nèi)容部分都是各不相同的,所以需要在子類中去重載,自己繪制

? 4.繪制子視圖,調(diào)用dispatchDraw()。如果視圖中沒有子視圖,就不需要繪制了。因此你會發(fā)現(xiàn)View中的dispatchDraw()方法又是一個空方法,而ViewGroup的dispatchDraw()方法中就會有具體的繪制代碼

? 5.如果要視圖顯示漸變框,這里開始繪制

? 6.繪制滾動條

?顯然 第2和第5步基本是用不到的。重要的是第3步。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容