Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲

繪圖機制

編輯:關於android開發

繪圖機制


Android中每一個組件的繪制過程,都要經過三個階段:測量、布局、繪制,分別對應著方法onMeasure、onLayout、onDraw(這三個方法定義於View類中)。當然,這三個方法都是允許組件自己重定義的方法,來實現組件對自己的尺寸進行測量(①有child views時,要分別對子組件調用相關測量方法,比如measureChild、measureChildWithMargins等,並根據子組件的dimension來確定自己的尺寸;②最後要調用setMeasuredDimension(measuredWidth, measuredHeight)方法來保存自己的尺寸信息。)、對自己進行布局(調用onLayout,如果是container,同樣需要對子組件進行布局,調用子組件的layout(int l, int t, int r, int b)方法,最終同樣會執行子組件的onLayout方法來實現對子組件的布局(布局說白了就是確定自己的繪制位置,即左上右下四個坐標),對於容器來說,將其中的具體組件布局好了,也就將其布局好了)以及繪制自己的內容(調用onDraw方法,使用該方法的參數Canvas進行內容繪制); 從代碼中看,Android的繪圖是從ViewRootImpl類的performTraversals方法開始的,可以把這個方法視為一個頂層的控制方法,在其中控制整個繪圖的流程。具體情況如下所述:

Ⅰ首先,在其中會調用performMeasure方法,在performMeasure方法中調用View的measure方法(View的measure是final方法,方法原型為:

public final void measure(int widthMeasureSpec, int heightMeasureSpec),

也就是說不允許子類修改測量的框架,只能夠修改真正進行測量工作的onMeasure方法),進而調用具體組件所實現的onMeasure方法。

Ⅱ然後,測量結束後會調用performLayout方法,在performLayout方法中調用View的layout方法,該方法原型為:

public void layout(int l, int t, int r, int b),

在該方法中會調用View的onLayout方法,對組件進行布局。

在拓展ViewGroup類的時候,對於所重寫的onLayout方法,一般最後一步就是分別調用組件各自的layout方法來“Place the child.”。

Ⅲ之後,會調用performDraw方法,通過performDraw -> draw -> drawSoftware最終會調用View的draw(Canvas)方法。在draw方法中會有六步操作,在第三步“draw the content”時會調用onDraw(Canvas)方法,進行內容的繪制。 總結:

如果我們要拓展ViewGroup類實現一個布局,就要在其中重寫onMeasure方法來對布局中的組件進行測量,並在獲得其中所有組件的尺寸後計算得到布局的尺寸,然後調用setMeasuredDimension方法進行設置;之後還需要重寫onLayout方法,在其中調用各個組件的layout方法,傳入計算出的組件坐標位置,實現對組件的布局。

至於繪制,則由具體的組件自己重寫onDraw方法進行實現,在ViewRootImpl類的performTraversals邏輯中進行控制。 附加:

①在測量結束後(調用方法setMeasuredDimension後),就可以調用getMeasuredWidth和getMeasuredHeight來獲取視圖測量出的寬和高了,在這之前這兩個方法返回值均為0;

在布局結束後,就可以調用方法getWidth和getHeight來獲取視圖的寬高了。

以上就是getMeasuredXXX與getXXX的區別,由於一般情況下,會根據測量的情況去布局組件,所以這兩個方法的返回值是一樣的。

②關於MeasureSpec

MeasureSpec由specSize與specMode兩部分組成,前者是大小信息,後者是模式信息。包括的模式有:

EXACTLY

表示父視圖希望子視圖的大小應該是由specSize的值來決定的,系統默認會按照這個規則來設置子視圖的大小,開發人員當然也可以按照自己的意願設置成任意的大小。

AT_MOST

表示子視圖最多只能是specSize中指定的大小,開發人員應該盡可能小得去設置這個視圖,並且保證不會超過specSize。系統默認會按照這個規則來設置子視圖的大小,開發人員當然也可以按照自己的意願設置成任意的大小。

UNSPECIFIED

表示開發人員可以將視圖按照自己的意願設置成任意的大小,沒有任何限制。這種情況比較少見,不太會用到。

MeasureSpec是一個32位的int數,其中的2位用來表示模式,余下30位用來表示size。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved