Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android View框架總結(六)View布局流程之Draw過程

Android View框架總結(六)View布局流程之Draw過程

編輯:關於Android編程

View的Draw時序圖

這裡寫圖片描述

前面幾篇通過對View樹的measure和layout過程分析事,接下來將結合前兩步得到的測量值及在視圖中的位位置,開始進行繪制操作,一步比一步復雜,draw過程比前面都要復雜,draw的不好,就會出現overdraw。下面請仔細看分析過程:
draw的原始觸發點還是在ViewRootImpl的performTraversals(執行遍歷)方法中,開始分析流程:可以結合我畫的時序圖一起看,方便理解。

ViewRootImpl.performTraversals()

這裡寫圖片描述

ViewRootImpl.performDraw()

這裡寫圖片描述

ViewRootImpl.draw()

這裡寫圖片描述

measure和layout過程直接調用的是ViewRootImpl的performMeasure和performLayout方法,draw調用的是ViewRootImpl的performDraw()方法,再由performDraw中的draw(boolean fullRedrawNeeded)方法來調用ViewTreeObserver中的dispatchOnDraw()方法,進行通知所有掛在view樹上的view開始draw。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoNCBpZD0="viewtreeobserverdispatchondraw">ViewTreeObserver.dispatchOnDraw()

這裡寫圖片描述

View.onDraw()

這裡寫圖片描述

對於View.java和ViewGroup.java,onDraw()默認都是空實現,因為具體View本身是什麼,這就是做框架,提供空間,你要在裡面自定義什麼view是使用者所決定,但是可以提供默認方法。

View.draw()

這裡寫圖片描述
這裡寫圖片描述這裡寫圖片描述

View的另一個draw方法

這裡寫圖片描述這裡寫圖片描述

View.drawBackground() — // Step 1, draw the background

這裡寫圖片描述這裡寫圖片描述

View.onDraw() — // Step 3, draw the content

這裡寫圖片描述

View.dispatchDraw() — // Step 4, draw the children

這裡寫圖片描述

View.onDrawScrollBars — // Step 6, draw decorations (foreground, scrollbars)

這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述

View中dispatchDraw()默認為空實現,因為其不包含子view,而ViewGroup重寫了dispatchDraw()來對其子view進行繪制,一般自定義view不應該對dispatchDraw()進行重載,因為它已經體現了View系統繪制的流程。那麼,接下來我們繼續分析下ViewGroup中dispatchDraw()的具體流程:

ViewGroup.dispatchDraw()

這裡寫圖片描述這裡寫圖片描述

ViewGroup.drawChild()

這裡寫圖片描述

dispatchDraw()的關鍵就是通過for循環調用drawChild()對ViewGroup的每個子視圖進行繪制,上述代碼中如果FLAG_USE_CHILD_DRAWING_ORDER為true,則子視圖的繪制順序通過getChildDrawingOrder來決定,默認的繪制順序即是子視圖加入ViewGroup的順序,而我們可以重載getChildDrawingOrder方法來更改默認的繪制順序,讓子view重疊在父view上,或者說是掛在父view上。 drawChild()的核心就是為子視圖分配合適的canvas畫布區,畫布區的size是d在layout過程決定的,而畫布區的位置取決於滾動值以及子視圖當前的動畫。設置畫布區後就會調用childview的draw()函數,如果childview的包含SKIP_DRAW標識,僅調用dispatchDraw(),即跳過子視圖本身的繪制,但要繪制視圖可能包含的childview。

ViewGroup.drawChild()

這裡寫圖片描述

這裡寫圖片描述

Draw過程小總結:

自定義View是一個ViewGroup,則需要遞歸繪制包含的所有子View。 View默認不會繪制任何內容,真正的繪制都需要自己在子類中實現,只是做好繪制流程,這就是框架的職責。 區分View動畫和ViewGroup布局動畫,前者指的是View自身的動畫,可以通過setAnimation添加,後者是專門針對ViewGroup顯示內部子視圖時設置的動畫,可以在xml布局文件中對ViewGroup設置layoutAnimation屬性(譬如對LinearLayout設置子View在顯示時出現逐行、隨機、下等顯示等不同動畫效果)。 在獲取畫布剪切區(每個View的draw中傳入的Canvas)時會自動處理掉padding,子View獲取Canvas不用關注這些邏輯,只用關心如何繪制即可。 默認情況下子View的ViewGroup.drawChild繪制順序和子View被添加的順序一致,但是你也可以重載ViewGroup.getChildDrawingOrder()方法提供不同順序。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved