您的位置:首页 > 移动开发 > Android开发

Android 绘制 View 机制(API 翻译)

2014-02-11 16:01 746 查看

How Android Draws Views

When an 
Activity
 receives focus, itwill be requested to draw its layout. The Android framework will handle the procedure for drawing, but the 
Activity
 mustprovide the root node of its layout hierarchy.Drawing begins with the root node of the layout. It is requested to measure and draw the layout tree. Drawing is handled by walking the tree and rendering each 
View
 thatintersects the invalid region. In turn, each 
ViewGroup
 isresponsible for requesting each of its children to be drawn (with the 
draw()
 method)and each 
View
 is responsible for drawingitself. Because the tree is traversed in-order, this means that parents will be drawn before (i.e., behind) their children, with siblings drawn in the order they appear in the tree.The framework will not draw 
View 
objectsthat are not in the invalid region, and also will take care of drawing the
View
 backgroundfor you.You can force a 
View
 todraw, by calling 
invalidate()
.1、Activity获取到焦点后,才开始绘制其布局。framework 负责处理绘制的过程,但是 Activity 必须提供布局层次上的根节点。2、绘制View是从根节点开始的,所以要求先测量和绘制 layout tree。绘制是有顺序的:ViewGroup负责发送请求,绘制他的children(调用draw( ));View 负责自己绘制自己:因为layout tree 的测量时有顺序的,也就是说,parents view 先绘制,child view 后面绘制。绘制child view 时候,是根据出现在 tree 上的顺序绘制的。Drawing the layout is a two pass process: a measure pass and a layout pass. The measuring pass is implemented in 
measure(int,
int)
 and is a top-down traversal of the 
View
 tree.Each 
View
 pushes dimension specificationsdown the tree during the recursion. At the end of the measure pass, every 
View
 hasstored its measurements. The second pass happens in 
layout(int,
int, int, int)
 and is also top-down. During this pass each parent is responsible for positioning all of its children using the sizes computed in the measure pass.1、绘制布局经历两个过程:测量,布局。    2、测量过程:用 measure(int,int) 实现,有顺序:从 tree 自上而下; 递归过程中,每个view 把自己的尺寸推送到tree中。测量过程的最后,每个view都会记录下自己的尺寸3、布局过程:layout(int, int, int, int)方法,也是自上而下。在这个过程中,每个 parent view负责把所有的children view放到合适的位置,用的参数是 测量过程中计算出来的尺寸。When a 
View
 object's 
measure()
 methodreturns, its 
getMeasuredWidth()
 and 
getMeasuredHeight()
 valuesmust be set, along with those for all of that 
View
 object'sdescendants. A 
View
 object's measuredwidth and measured height values must respect the constraints imposed by the 
View
 object'sparents. This guarantees that at the end of the measure pass, all parents accept all of their children's measurements. A parent 
View
 may call 
measure()
morethan once on its children. For example, the parent may measure each child once with unspecified dimensions to find out how big they want to be, then call 
measure()
 onthem again with actual numbers if the sum of all the children's unconstrained sizes is too big or too small (that is, if the children don't agree among themselves as to how much space they each get, the parent will intervene and set the rules on the secondpass).To initiate a layout, call 
requestLayout()
.This method is typically called by a 
View
 onitself when it believes that is can no longer fit within its current bounds.1、measure()执行完毕,那么 
getMeasuredWidth()
 and 
getMeasuredHeight() 的值就必须被设定了。view的子孙view也是一样的.
2、children view 测量宽度和高度的时候,必须注意 parent view的约束。(不能比父控件大)(需要测试一下) 这样才能保证:测量过程结束的时候,所有的parents 才能接受children view的尺寸。
3、有时候,parent在测量child 的时候可能调用多于一次的  measure(),比如:parent测量child
一次,测量尺寸没有限制大小,只是测量,child view 想要让自己多大。
如果所有children view的尺寸不满足要求,太大或者太小了,那么再次调用 measure()去测量
children view,获取children 的实际尺寸。(两者不达成一致,第二次测量的时候,parent将添加限制规则,强制固定大小)
The measure pass uses two classes to communicate dimensions. The 
ViewGroup.LayoutParams
 classis used by 
View
 objects to tell theirparents how they want to be measured and positioned. The base 
ViewGroup.LayoutParams
 classjust describes how big the 
View 
wantsto be for both width and height. For each dimension, it can specify one of:an exact number
MATCH_PARENT
,which means the 
View
 wants to be as bigas its parent (minus padding)
WRAP_CONTENT
,which means that the 
View
 wants to bejust big enough to enclose its content (plus padding).1、测量过程中使用到两个类去传达尺寸(ViewGroup.LayoutParamsMeasureSpec): 
ViewGroup.LayoutParams:用于子view告诉父view,想自己怎么被测量,被摆放。基本的 ViewGroup.LayoutParams 仅仅是描述view想要自己多高,多宽。可以指定:
MATCH_PARENT:和父view一样大,减去padding
?
[/code]
WRAP_CONTENT:足够大小,包裹自己的内容,加上padding
? 
There are subclasses of 
ViewGroup.LayoutParams
 fordifferent subclasses of 
ViewGroup
.For example,
RelativeLayout
 hasits own subclass of 
ViewGroup.LayoutParams
,which includes the ability to center child 
View
objectshorizontally and vertically.1、针对 
ViewGroup
不同的子类,有其对应的不同的  
ViewGroup.LayoutParams
 。力例如:
RelativeLayout就有自己对应ViewGroup.LayoutParams的子类,里面包含了把子view摆放成垂直还是水平
各种布局都是ViewGroup,各种布局之间的属性是不一样的,每个布局有不同的  
ViewGroup.LayoutParams
 
MeasureSpec
 objects are usedto push requirements down the tree from parent to child. A 
MeasureSpec
 canbe in one of three modes:
UNSPECIFIED
:This is used by a parent to determine the desired dimension of a child 
View
.For example, a 
LinearLayout
 maycall 
measure()
 on itschild with the height set to 
UNSPECIFIED
 anda width of 
EXACTLY
 240to find out how tall the child 
View
 wantsto be given a width of 240 pixels.
EXACTLY
:This is used by the parent to impose an exact size on the child. The child must use this size, and guarantee that all of its descendants will fit within this size.
AT
MOST
: This is used by the parent to impose a maximum size on the child. The child must guarantee that it and all of its descendants will fit within this size.1、MeasureSpec 对象用于把要求从parent向child向下推送。   
MeasureSpec 有三种模式:
UNSPECIFIED:不限制:子view想要多大,parnet就给你多大,比如: 
LinearLayout设置高度的时候用 UNSPECIFIED,设置宽度的时候,用 EXACTLY 240像素
EXACTLY:指定准确尺寸:parent强加到child view一个实际尺寸,child 必须使用,并且保证 child 的所有子孙 view 都满足条件
AT
MOST:限制最大尺寸:parent 限制child 的最大尺寸。child 必须遵守,并且 child 的所有子孙都满足
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: