1. 程式人生 > >安卓View的繪製流程和機制

安卓View的繪製流程和機制

View系統的繪製流程會從ViewRoot的performTraversals()方法中開始,performTraversals()的意思是:執行遍歷


View的整個繪製流程可以分為以下三個階段:

measure: 判斷是否需要重新計算View的大小,需要的話則計算;
layout: 判斷是否需要重新計算View的位置,需要的話則計算;
draw: 判斷是否需要重新繪製View,需要的話則重繪製。
measure()、layout()、draw(),其內部又分別包含了onMeasure()、onLayout()、onDraw()三個子方法。
 

View樹的繪製是一個遞迴的過程,從ViewGroup一直向下遍歷,直到所有的子view都完成繪製,那這一切的源頭在什麼地方(是誰最發起measure、layout和draw的)?當然就是在View樹的源頭了——ViewRoot!,ViewRoot中包含了視窗的總容器DecorView,ViewRoot中的performTraversal()方法會依次呼叫decorView的measure、layout、draw方法,從而完成view樹的繪製。
 

onAttachedToWindow () 和 onDetachedFromWindow () 
onAttachedToWindow是在第一次onDraw前呼叫的。也就是我們寫的View在沒有繪製出來時呼叫的,但只會呼叫一次。
onDetachedFromWindow:銷燬資源(既銷燬view)之後呼叫。

veiw狀態的保持:onSaveInstanceState()方法

invalidate()是用來重新整理View的,必須是在UI執行緒中進行工作。比如在修改某個view的顯示時,呼叫invalidate()才能

看到重新繪製的介面。invalidate()的呼叫是把之前的舊的view從主UI執行緒佇列中pop掉。

invalidate()得在UI執行緒中被調動,在工作者執行緒中可以通過Handler來通知UI執行緒進行介面更新。而postInvalidate()在工作者執行緒中被呼叫。

Android View重新整理機制

        由ViewRoot物件的performTraversals()方法呼叫draw()方法發起繪製該View樹,值得注意的是每次發起繪圖時,並不會重新繪製每個View樹的檢視,而只會重新繪製那些“需要重繪”的檢視,View類內部變數包含了一個標誌位DRAWN,當該檢視需要重繪時,就會為該View新增該標誌位。

        呼叫流程 : 

        mView.draw()開始繪製,draw()方法實現的功能如下:

        繪製該View的背景

        為顯示漸變框做一些準備操作(見5,大多數情況下,不需要改漸變框)          

        呼叫onDraw()方法繪製檢視本身   (每個View都需要過載該方法,ViewGroup不需要實現該方法)

        呼叫dispatchDraw ()方法繪製子檢視(如果該View型別不為ViewGroup,即不包含子檢視,不需要過載該方法)值得說明的是,ViewGroup類已經為我們重寫了dispatchDraw ()的功能實現,應用程式一般不需要重寫該方法,但可以過載父類函式實現具體的功能。

在Android的佈局體系中,父View負責重新整理、佈局顯示子View;而當子View需要重新整理時,則是通知父View來完成。這種處理邏輯在View的程式碼中明確的表現出來:

子View呼叫invalidate時,首先找到自己父View(View的成員變數mParent記錄自己的父View),然後將AttachInfo中儲存的資訊告訴父View重新整理自己。
 

 

 

參考:https://blog.csdn.net/yanbober/article/details/46128379

https://blog.csdn.net/kc58236582/article/details/52411791