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

來源:互聯網
上載者:User

標籤:

轉載請註明出處:http://blog.csdn.net/hejjunlin/article/details/52236145

  • View的Draw時序圖
  • ViewRootImpl.performTraversals過程
  • ViewRootImpl.performDraw過程
  • View.draw方法
  • View.dispatchDraw過程
  • LinearLayout的onDraw過程
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。

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()方法提供不同順序。

第一時間獲得部落格更新提醒,以及更多android乾貨,源碼分析,歡迎關注我的公眾號,掃一掃下方二維碼或者長按識別二維碼,即可關注。

如果你覺得好,隨手點贊,也是對筆者的肯定,也可以分享此公眾號給你更多的人,原創不易

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.