Android 绘制 View 机制(API 翻译)

How Android Draws Views

When an Activity receives focus, it will be requested to draw its layout. The Android framework will handle the procedure for drawing, but the Activity must provide 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 that intersects the invalid region. In turn, each ViewGroup is responsible for requesting each of its children to be drawn (with the draw() method) and each View is responsible for drawing itself. 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.

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 specifications down the tree during the recursion. At the end of the measure pass, every View has stored 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() method returns, its getMeasuredWidth() and getMeasuredHeight() values must be set, along with those for all of that View object's descendants. A View object's measured width and measured height values must respect the constraints imposed by the View object's parents. 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()more than 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() on them 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 second pass).

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 class is used by View objects to tell their parents how they want to be measured and positioned. The base ViewGroup.LayoutParams class just describes how big the View wants to 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 big as its parent (minus padding)
  • WRAP_CONTENT, which means that the View wants to be just big enough to enclose its content (plus padding).
1、测量过程中使用到两个类去传达尺寸(ViewGroup.LayoutParamsMeasureSpec): ViewGroup.LayoutParams:用于子view告诉父view,想自己怎么被测量,被摆放。基本的 ViewGroup.LayoutParams 仅仅是描述view想要自己多高,多宽。可以指定:
MATCH_PARENT:和父view一样大,减去padding ?
WRAP_CONTENT:足够大小,包裹自己的内容,加上padding ? 

There are subclasses of ViewGroup.LayoutParams for different subclasses of ViewGroup. For example,RelativeLayout has its own subclass of ViewGroup.LayoutParams, which includes the ability to center child Viewobjects horizontally and vertically.

1、针对 ViewGroup不同的子类,有其对应的不同的  ViewGroup.LayoutParams 。力例如:RelativeLayout就有自己对应ViewGroup.LayoutParams的子类,里面包含了把子view摆放成垂直还是水平

各种布局都是ViewGroup,各种布局之间的属性是不一样的,每个布局有不同的  ViewGroup.LayoutParams 

MeasureSpec objects are used to push requirements down the tree from parent to child. A MeasureSpec can be 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 may call measure() on its child with the height set to UNSPECIFIED and a width of EXACTLY 240 to find out how tall the child View wants to 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 的所有子孙都满足

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值