AndroidUI繪製流程,一步一步深入原始碼解析(五)view繪製
View的繪製:
四個關鍵步驟:
1、繪製背景 drawBackgroud(canvas)
2、繪製自己 onDraw(canvas)
3、繪製子VIew dispatchDraw(canvas)
4、繪製前景,滾動條等裝飾 onDrawForeground(canvas)
前幾篇我們分析過,知道view的繪製三大流程,performMeasure,performLayout以及performDraw
測量、佈局都已經分析過了,現在我們分析繪製流程
先從performDraw原始碼開始講起
/ frameworks / base / core / java / android / view / ViewRootImpl.java

這裡我們看到主要是呼叫了draw方法,後面的一些程式碼都不是主要程式碼,接著看draw方法原始碼,

這裡找到一句關鍵程式碼,又呼叫了drawSoftware方法

最終我們找到mView.draw(canvas)方法,這裡mView就是DecorView,所以我們直接去看它的父類View的draw方法,

這裡就很容易理解了,註釋寫的很清楚,關鍵步驟一共6個,
* Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
* 1. Draw the background
* 2. If necessary, save the canvas' layers to prepare for fading
* 3. Draw view's content
* 4. Draw children
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
*/
那我們就一步一步看是怎麼繪製的,
繪製背景:

這裡主要的繪製程式碼是backgroung.draw(canvas),這是Drawable類的一個抽象方法,具體的實現會根據不同的Drawable型別來具體實現,Drawable又很多子類,比如.9png是NinePatchDrawable,按下狀態的是StateListDrawable等等,都在android.graphic包中,現在我們只分析BitmapDrawable是怎麼實現的,先看原始碼
/ frameworks / base / graphics / java / android / graphics / drawable / BitmapDrawable.java

這裡都是一些程式碼邏輯,主要繪製功能都是由Canvas完成的,以後有機會我會詳細分析Canvas和Paint的繪製邏輯以及高階使用方式;
繪製自己:

這是個空方法,需要子類自己實現,因為不同的View有著不同的內容,這需要我們自己去實現,即在自定義View中重寫該方法來實現。
繪製子view:
如果當前的View是一個ViewGroup型別,那麼就需要繪製它的子View,這裡呼叫了dispatchDraw,而View中該方法是空實現,實際是ViewGroup重寫了這個方法,那麼我們來看看原始碼,ViewGroup.dispatchDraw

還是看關鍵程式碼,梳理大概的邏輯就是迴圈遍歷每個子view,並呼叫drawChild方法,

drawChild中又呼叫了View的draw方法,
/**
* This method is called by ViewGroup.drawChild() to have each child view draw itself.
*
* This is where the View specializes rendering behavior based on layer type,
* and hardware acceleration.
*/
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {}
主要來看核心部分,

首先判斷是否已經有快取,即之前是否已經繪製過一次了,如果沒有,則會呼叫draw(canvas)方法,開始正常的繪製,即上面所說的六個步驟,否則利用快取來顯示。
這一步也可以歸納為ViewGroup繪製過程,它對子View進行了繪製,而子View又會呼叫自身的draw方法來繪製自身,這樣不斷遍歷子View及子View的不斷對自身的繪製,從而使得View樹完成繪製。
繪製裝飾品:

邏輯很清晰,和一般的繪製流程非常相似,都是先設定繪製區域,然後利用canvas進行繪製。
到這裡AndroidUI繪製流程這大模組就分析完了,後續我會抽空寫以下Canvas和Paint相關的高階使用技巧。