天天看點

Android view的測量及繪制

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"

Android view的測量及繪制

(2)android:layout_width="match_parent"

Android view的測量及繪制

(3)android:layout_width="400px"

Android view的測量及繪制

  view的繪制:

  對view進行繪制需要重寫onDraw()方法,onDraw()方法中會有一個canvas,可以把這個參數了解成畫闆,我們最終會借用這個畫闆進行繪制。

有了畫闆,要想繪畫的話當然還需要一支畫筆paint。

  接下講解一下這段代碼的功能,首先執行個體了兩隻畫筆,并且對畫筆設定了顔色和風格,接下來開始繪制,這裡我們畫的是兩個互相嵌套的橢圓,

canvas.drawOval(0,0,getMeasuredWidth(),getMeasuredHeight(),paint1);這個方法需要5個入參,分别是view相對于父布局的左、上、右、下的坐标,最後一個是進行繪制的畫筆。

  系統給我們提供的drawXXX方法有很多:

效果展示:

Android view的測量及繪制

  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,如需轉載請自行聯系原作者

繼續閱讀