view的測量:
首先需要知道的是view的三種測量模式:
1、EXACTLY:精确值模式,當我們對view的layout_width和layout_height屬性指定具體的數值的時候,比如layout_width=“100dp”或者指定為match_parent時,系統
進行測量的時候,使用的是這種模式。
2、AT_MOST:最大值模式,當我們對view的layout_width和layout_height屬性指定為wrap_content時,即view随着内容的大小變化而變化,或viewgroup随着view的
大小變化而變化,這個時候系統進行測量的時候,使用的是這種模式。
3、UNSPECIFIED:這個屬性下不用指定其大小,一般在自定義view時才會使用(這種模式不是很了解,求指教)
在對view進行測量的時候,需要重寫onMeasure()方法,view預設的onMeasure()方法隻支援EXACTLY模式,即指定具體的數值,是以在自定義view的時候必須重寫
onMeasure(),這裡留一個疑問:什麼時候才會調用Measure方法進行測量?
重寫後點super.onMeasure(widthMeasureSpec, heightMeasureSpec);進去看一下源碼,發現系統最終會調用這個方法:
這個方法的作用是将我們對view設定的寬和高設定進去,是以我們最終重寫的onMeasure()方法就是這個樣子的,方法内的兩個入參widthMeasureSpec和heightMeasureSpec
就是我們在xml裡引用這個view時設定的width和height,後面我們需要根據這兩個值進行判斷,判斷系統要根據什麼測量模式進行測量。
前文一直在說系統的測量模式,那麼我們要怎麼樣才能擷取到系統的測量模式呢?擷取測量模式後還需要擷取具體的測量大小
單獨對measureWidth(widthMeasureSpec)講解一下,因為height和width是一樣的。
這部分的了解要聯系到前面說的3種測量模式,如果是在EXACTLY if (specMode == MeasureSpec.EXACTLY) 這種模式下,我們已經在xml裡面設定好了具體的數值,是以最後傳回的值就是specSize
如果是AT_MOST和UNSPECIFIED這兩種測量模式下,我們就需要給view一個預設的大小,因為如果沒有給預設的大小的話,系統不知道view的大小,是以view或預設充滿父布局。這裡預設的大小是400,
大家會發現else裡面還有一個if,對AT_MOST這種模式又進行了判斷,這是因為在這種模式下,view不需要預設的大小,view的是根據内容的大小變換而變化的。
最後就是xml裡面進行引用和效果展示了:
(1)android:layout_width="wrap_content"

(2)android:layout_width="match_parent"
(3)android:layout_width="400px"
view的繪制:
對view進行繪制需要重寫onDraw()方法,onDraw()方法中會有一個canvas,可以把這個參數了解成畫闆,我們最終會借用這個畫闆進行繪制。
有了畫闆,要想繪畫的話當然還需要一支畫筆paint。
接下講解一下這段代碼的功能,首先執行個體了兩隻畫筆,并且對畫筆設定了顔色和風格,接下來開始繪制,這裡我們畫的是兩個互相嵌套的橢圓,
canvas.drawOval(0,0,getMeasuredWidth(),getMeasuredHeight(),paint1);這個方法需要5個入參,分别是view相對于父布局的左、上、右、下的坐标,最後一個是進行繪制的畫筆。
系統給我們提供的drawXXX方法有很多:
效果展示:
viewGroup的測量:
我們知道viewGroup管理子view,那麼viewGroup的大小,除設定指定大小外,是根據子view來決定的,viewGroup在測量時會周遊所有的子view,調用
子view的Measure方法來獲得每一個子view的測量結果,這樣文章開始留下的疑問就解決了,意不意外~關于viewGroup的繪制,一般情況下如果不是指定
了viewGroup的背景顔色,viewGroup的onDraw()方法不會被調用,但是viewGroup會使用dispatchDraw()方法來繪制其子view,過程同樣是周遊所有的子view
,并調用子view的繪制方法來完成繪制。
本文轉自xmgdc51CTO部落格,原文連結:http://blog.51cto.com/12953214/1942325,如需轉載請自行聯系原作者