
記清楚函數(shù)調(diào)用的順序才能準(zhǔn)確地進(jìn)行調(diào)用。
根據(jù)調(diào)用鏈,可將整個(gè)繪制過程分為三部分:Measure - Layout - Draw
Measure 過程
- 測(cè)量過程由上至下,在measure過程的最后,每個(gè)視圖將存儲(chǔ)自己的尺寸大小和測(cè)量規(guī)格。
- measure過程會(huì)為一個(gè)View及其所有子節(jié)點(diǎn)的mMeasureWidth和mMeasuredHeight變量賦值, 該值可以通過getMeasuredWidth和getMeasuredHeight方法獲得。
-
measure過程的核心方法:** measure() - onMeasure() - setMeasuredDimension(). **
** setMeasuredDimension**是測(cè)量階段的終極方法,在onMeasure()方法中調(diào)用,將計(jì)算得到的尺寸,傳遞給該方法,測(cè)量階段結(jié)束。在自定義 視圖時(shí),不需要關(guān)心系統(tǒng)復(fù)雜的Measure過程,只需要調(diào)用setMeasuredDimension()設(shè)置根據(jù)MeasureSpec計(jì)算得到的尺寸即可。同時(shí), onMeasure()方法也必須調(diào)用setMeasuredDimension()方法來設(shè)置重新測(cè)量之后的
以measureChildren為例的調(diào)用鏈圖:
Layout 過程
- 子視圖的具體位置都是相對(duì)于父視圖而言的。View的onLayout()方法為空實(shí)現(xiàn),而ViewGroup的onLayout為abstract,因此,自定義的View要繼承ViewGroup時(shí),必須實(shí)現(xiàn)onLayout函數(shù)。
- 在Layout過程中,子視圖會(huì)調(diào)用getMeasuredWidth()和getMeasuredHeight()方法獲取到measure過程得到mMeasuredWidth和mMeasuredHeight,作為自己的width和height。然后調(diào)用每一個(gè)子視圖的layout(),來確定每個(gè)子視圖在父視圖中的位置。
Draw 過程 - 所有視圖最終都是調(diào)用View的draw方法進(jìn)行繪制。 在自定義視圖中, 也不應(yīng)該復(fù)寫該方法, 而是復(fù)寫onDraw()方法進(jìn)行繪制, 如果自定義的視圖確實(shí)要復(fù)寫該方法,先調(diào)用super.draw()完成系統(tǒng)的繪制,再進(jìn)行自定義的繪制。
- onDraw()方法默認(rèn)是空實(shí)現(xiàn),自定義繪制過程需要復(fù)寫方法,繪制自身的內(nèi)容。
- dispatchDraw()發(fā)起對(duì)子視圖的繪制,在View中默認(rèn)為空實(shí)現(xiàn),ViewGroup復(fù)寫了dispatchDraw()來對(duì)其子視圖進(jìn)行繪制。自定義的ViewGroup不應(yīng)該對(duì)dispatchDraw()進(jìn)行復(fù)寫。
如何對(duì)自定義View進(jìn)行控制 - 如果想控制View在屏幕上的渲染效果,就在重寫onDraw()方法,在里面進(jìn)行相應(yīng)的處理。
- 如果想要控制用戶同View之間的交互操作,則在onTouchEvent()方法中對(duì)手勢(shì)進(jìn)行控制處理。
- 如果想要控制View中內(nèi)容在屏幕上顯示的尺寸大小,就重寫onMeasure()方法中進(jìn)行處理。
- 在 XML文件中設(shè)置自定義View的XML屬性。
- 如果想避免失去View的相關(guān)狀態(tài)參數(shù)的話,就在onSaveInstanceState() 和 onRestoreInstanceState()方法中保存有關(guān)View的狀態(tài)信息。
文/wusp(簡(jiǎn)書作者)原文鏈接:http://www.itdecent.cn/p/f0bc39dbfa26著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),并標(biāo)注“簡(jiǎn)書作者”。
