android如何绘制视图

当Activity获得焦点时,它需要绘制布局。Android框架会处理绘制的过程,但是Activity必须提供布局层级的根节点。

绘制从layout的根节点开始,需要测量和绘制layout树。绘图需要遍历树节点并且呈现每个子视图在有效区域的部分。因此,每个ViewGroup负责通知它的子视图绘制(通过draw()方法),并且每个View负责绘制它自己。因为树是有序遍历的,这意味着父节点比子节点早绘制。兄弟节点按在树中出现的位置绘制。

绘制布局有2个传递过程:测量传递(measure mass)和布局传递(layout pass)。测量传递在方法 measure(int, int)中实现,并且在View树中自顶向下遍历。在递归中,树中的每个View对象向下推送尺寸规格。在测量传递结束后,每个view存储它自己的尺寸。第二次传递发生在 layout(int, int, int, int),同样是自顶向下的。通过这次传递,每个父View负责根据measure测量到的尺寸安排子视图的位置。

tips:

框架不会在不可达区域绘制View,同样会注意绘制View的背景。你可以调用invalidate()方法强制重绘View。

当一个View对象的measure() 方法返回时,它的 getMeasuredWidth() 和 getMeasuredHeight()值必须已经被设置,对于它们的子节点也同样是。一个View对象在测量宽和高时必须遵循其父View的约束。这保证了测量结束后,所有父view能容纳它们子view的尺寸。父View可能在它的子View上多次调用measure()。比如,父view可能测量每个没有指明尺寸的子view一次,以发现它们需要多大的空间,然后对它们再次调用measure(),以确定的参数(如果所有子view的原始尺寸过大或者太小,也就是说,如果子view们不认可自己能获得的空间大小,父view第二次测量会干涉并且制定规则)。

测量过程用2个类来交流尺寸,ViewGroup.LayoutParams 类被View对象用于告诉他们的父view它们想要如何被测量和布置位置。ViewGroup.LayoutParams类描述了View对象需要的高和宽。对于每个尺寸,它可以指定为:

1.一个具体的数字

2.MATCH_PARENT:意味着view想要和父view一样大(减去padding值)

3.WRAP_CONTENT:意味着view只需要足够包裹它自身子view的大小(加上padding值)

MeasureSpec对象用于父view向子view推送请求,有3种模式

UNSPECIFIED:用于让父view决定子view的尺寸。比如,一个LinearLayout可能在子节点上调用measure(),把高度设置为UNSPECIFIED,宽度设为EXACTLY 240来找出子view在240的宽度下需要多大的高度。

EXACTLY:用于父view指定子view确切的大小。子节点必须使用这个尺寸,而且保证其子view也都适应这个尺寸

AT MOST:用于指定子view最大的尺寸,子节点保证其子view也都适应这个尺寸


翻译地址:http://developer.android.com/guide/topics/ui/how-android-draws.html

你可能感兴趣的:(android如何绘制视图)