相關的類:
------------------------------------------------------------------------------------------------------------------------------------------------------------------
View
android中所有的可視組件都繼承自View,View定義了很多callbacks來定義它的行爲,如onDraw(),onMeasure()等。
ViewParent (interface)
ViewParent爲所有想扮演其他views的父親的類定義了協議。
ViewGroup (extends View and implements ViewParent)
所有Layout都繼承自ViewGroup,如LinearLayout。它負責在XML中定義Layout,擺放controls(views)到正確的位置。
它還負責child views的背景和動畫。
ViewRoot (implements ViewParent)
ViewRoot相當於中央控制樞紐,他是activity中所有view的根父類。它的職責是:1.ViewRoot調度遍歷所有的views爲了把
views以正確的尺寸擺放到正確的位置,這一階段叫做layout階段;2.ViewRoot遍歷view的層級,爲了把views畫出來,
這一階段叫做drawing階段。
Layout 階段: Measure + Layout
------------------------------------------------------------------------------------------------------------------------------------------------------------------
在Layout階段ViewRoot只會遍歷那些請求layout變化的views,這種條件遍歷是爲了節省資源,提高響應時間。想改變layout的
view只需callrequestLayout()方法。這個call會沿着view層級一直往上走,直到到達ViewRoot。然後ViewRoot在main線程隊列裏
調度佈局遍歷的消息。
layout階段分兩步走,measure + layout 。
measure由View Class的measure()函數實現。此函數的簽名是:
public final void measure(int widthMeasureSpec, int heightMeasureSpec) 。
measure()做一些整理打掃之類的工作,然後call 衍生類(暫且叫它SubViews)的onMeasure()方法。SubViews通過call
setMeasuredDimension() 方法來設置它的尺寸。這些被設置到SubViews 的尺寸會被layout利用。在此上下文中,你只需override
View.onMeasure()方法( onMeasure()方法有缺省實現,缺省實現通過layout files 來決定你的view的尺寸)。大部分情況下你只需
關心onMeasure()方法就足夠了,但如果你自定義ViewGroup,你就需要在你的onMeasure() 方法裏call 每個child views 的measure()方法。
measure 之後每個view 都知道了自己的尺寸,然後控制權交到layout。
layout 由layout() 實現,它的方法簽名是:
public void layout(int left, int top, int right, int bottom)
layout() 會先後callonSizeChanged() ,onLayout() 方法。它們的簽名如下:
protected void onSizeChanged(int w, int h, int oldw, int oldh);
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
layout() call onLayout() 來允許像ViewGroup 在它的子views 裏call layout() 。至此Layout階段完成。
Drawing 階段
------------------------------------------------------------------------------------------------------------------------------------------------------------------
draw 的遍歷由View.draw()實現,draw()方法要做的事情有:
- Draw the background
- Draw view's content by delegating to onDraw()
- Draw children by delegating to dispatchDraw()
- Draw decorations such as scroll bars
- public void onDraw(...)
- public void dispatchDraw(...)
------------------------------------------------------------------------------------------------------------------------------------------------------------------
- onMeasure
- onSizeChanged
- onLayout
- onDraw
- dispatchDraw
這種模式叫做template/hook ,例如draw() 是template 方法,它以某種方式固定了行爲,然而又依賴hook onDraw() 來特殊化它自己。
- onMeasure(...)
- onDraw(...)