【翻译】(26)Android如何绘画视图
?
see
http://developer.android.com/guide/topics/ui/how-android-draws.html
?
原文见
http://developer.android.com/guide/topics/ui/how-android-draws.html
?
-------------------------------
?
How Android Draws Views
?
Android如何绘画视图
?
-------------------------------
?
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.
?
当一个活动接收焦点,它将被请求绘画它的布局。Android框架将处理绘画的过程,但Activity必须提供它的布局层级的根节点。
?
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 View group 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.
?
绘画从布局的根节点开始。它被请求度量和绘画布局树。绘画通过遍历树来处理并且渲染每个与不可用区域相交的视图。反过来,每个View组有责任请求它的每个子对象被绘画(用draw()方法)并且每个View有责任绘画它自己。因为树是按次序遍历,这意味着父节点将在它们的子对象之前(即叠在后面)被绘画,而同级对象根据它们在树中出现的次序绘画。
?
-------------------------------
?
The framework will not draw Views that are not in the invalid region, and also will take care of drawing the Views background for you.
?
框架将不绘画不再不可用区域内的View,同时还将小心地为你绘画View的背景。
?
You can force a View to draw, by calling invalidate().
?
你可以强制一个View绘画,通过调用invalidate()。
?
-------------------------------
?
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.
?
绘画布局是两个传递过程:一个度量传递和一个布局传递。度量传递由measure(int, int)实现并且是View树的自上而下遍历。每个View把尺寸规范在递归期间沿着树向下推。在度量传递的最后,每个View已经存储它的度量。第二个传递发生在layout(int, int, int, int)中,也是自上而下。在这个传递期间父对象有责任定位它的所有子对象,使用在度量传递中计算的大小。
?
When a View's measure() method returns, its getMeasuredWidth() and getMeasuredHeight() values must be set, along with those for all of that View's descendants. A View's measured width and measured height values must respect the constraints imposed by the View'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 (i.e., 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).
?
当一个View的measure()返回时,它的getMeasuredWidth()和getMeasuredHeight()的值必须被设置,伴随着对于那个View的后代的所有那些值。一个View的度量宽度和度量高度值必须考虑View的父对象所强加的约束。它保证在度量传递的最后,所有父对象接受它们的所有子对象的度量。一个父视图可以在它的子对象上调用measure()多于一次。例如,父对象可能用未指定的尺寸度量每个子对象一次以计算出他们希望有多大,然后再次用实际成员调用measure(),如果所有子对象的不受约束大小的总和太大或者太小(即,如果子对象不同意它们自己关于它们每一个得到多大的空间,父对象将在第二次传递中介入并设置规则)
?
-------------------------------
?
To initiate a layout, call requestLayout(). This method is typically called by a View on itself when it believes that is can no longer fit within its current bounds.
?
为了初始化一个布局,请调用requestLayout()。这个方法通常被一个View调用在它自己身上,在其相信不再可以适应它的当前范围的时候。
?
-------------------------------
?
The measure pass uses two classes to communicate dimensions. The View.MeasureSpec class is used by Views to tell their parents how they want to be measured and positioned. The base LayoutParams class just describes how big the View wants to be for both width and height. For each dimension, it can specify one of:
?
度量传递使用两个类以传递尺寸。View.MeasureSpec类被View使用以告诉他们的父对象他们希望如何被度量和定位。LayoutParams基类只是描述该View对于宽和高希望有多大。对于每个尺寸,它可以指定以下其中一种值:
?
* an exact number
?
* 一个精确数
?
* FILL_PARENT, which means the View wants to be as big as its parent (minus padding)
?
* FILL_PARENT,它意味着View希望和它的父对象同样地大(减去内边距)
?
* WRAP_CONTENT, which means that the View wants to be just big enough to enclose its content (plus padding).
?
* WRAP_CONTENT,它意味着View希望的正好足够地大来装载它的内容(减去内边距)。
?
There are subclasses of LayoutParams for different subclasses of ViewGroup. For example, RelativeLayout has its own subclass of LayoutParams, which includes the ability to center child Views horizontally and vertically.
?
有几个LayoutParams的子类用于不同的ViewGroup子类。例如,RelativeLayout拥有它自己的LayoutParams子类,它包含水平地或垂直地居中子View的能力。
?
MeasureSpecs are used to push requirements down the tree from parent to child. A MeasureSpec can be in one of three modes:
?
MeasureSpecs被用于从父到子向下推要求。MeasureSpec可以是三种模式的其中一种:
?
* 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.
?
* UNSPECIFIED:这是父对象使用以决定子View的期待尺寸。例如,一个LinearLayout可以在它的子对象上调用measure(),高度设置为UNSPECIFIED,而宽度设置为准确的240以计算出在给定宽度为240像素时子View想要有多高。
?
* 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.
?
* EXACTLY:这是父对象使用以强制在子对象上的一个精确大小。子对象必须使用这个大小,并且保证它的所有后代将适合这个大小。
?
* 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.
?
* AT_MOST:这是父对象使用以强制在子对象上的一个最大大小。子对象必须保证它和它的所有后代将适合这个大小。
?
Except as noted, this content is licensed under Apache 2.0. For details and restrictions, see the Content License.
?
除特别说明外,本文在Apache 2.0下许可。细节和限制请参考内容许可证。
?
Android 4.0 r1 - 16 Dec 2011 21:54
?
-------------------------------
?
Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
?
(此页部分内容基于Android开源项目,以及使用根据创作公共2.5来源许可证描述的条款进行修改)
?