相关的类:
------------------------------------------------------------------------------------------------------------------------------------------------------------------
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(...)