Android 用户界面---Android如何描画View(How Android Draws Views)

Activity收到焦点时,就会请求描画它的布局。Android框架将处理这个描画过程,但是Activity必须提供它的布局层次的跟节点。

描画从布局的根节点开始。它要度量和描画布局树。描画是通过遍历整个布局树来处理的,并在遍历过程中呈现每个与无效区域相交的View对象。每个ViewGroup依次负责请求它的每个子View进行描画(使用draw()方法),每个View对象负责描画自己。因为布局树是依次遍历的,这就意味着父节点将在它的子节点之前进行描画,而同级节点则会按照它们在树中的显示顺序来描画。

描画布局有两个过程:度量和布局。度量过程是在measure(int, int)方法中实现的,它是一个自上而下的遍历过程。在递归期间,每个View都会把它的尺寸规格向下传递。在度量过程的最后,每个View对象都会保存它们自己的尺寸。布局过程是发生在layout(int, int, int, int)方法中,并且它也是自上而下的过程,在这个过程期间,每个父容器都会使用在度量过程中计算的尺寸来定位它的子对象。

当一个View对象的measure()方法返回时,它的getMeasuredWidth()getMeasuredHeight()方法(包括这个View对象所包含的所有的子对象)的返回值必须是有意义的。一个View对象的度量宽度和度量高度必须严格遵守它的父容器的约束。这样就保证了在度量过程结束后,所有的父容器都能接收它们所有的子节点的尺寸。一个父View对象可以多次调用它子节点的measure()方法。例如,在未度量尺寸之前,父View先对每个子节点度量一次,以便发现它们所需要的大小,如果它的所有的子节点的未被约束之前的尺寸太多或太小,那么父节点就会在调用一次measure()方法,并分配给它们实际的大小(如果子节点所获得的空间不能满足自身的需要,那么父节点就介入并设置规则,然后进行第二次遍历)。

度量过程使用两个类来传递尺寸。View.MeasureSpec类用于告诉它们的父节点,它们想要如何度量和定位。LayoutParams类则用于描述View对象想要的宽度和高度。每个尺寸,都可以使用下列方式之一来指定:

1.  精确的数字

2.  FILL_PARENT:这意味着View对象想要跟它的父容器一样大(减去边距)

3.  WRAP_CONTENT:这意味着View对象只想要跟它的内容相匹配的空间(加上边距)

不同的ViewGroup子类会有对应的LayoutParams子类,如,RelativeLayout就有它自己的LayoutParams子类,它包含了让它的子View水平和垂直居中的能力。

MeasureSpecs类用于把要求从父节点向下传给子节点。MeasureSpec可以是以下三种模式之一:

1.  UNSPECIFIED:

父节点使用这种模式来确定它的子节点所期望的尺寸。如,LinearLayout可以调用一个高度设置为UNSPECIFIED、宽度设置设置为EXACTLY 240的子节点的measure()方法,来度量给定宽度为240像素的View对象的高度。

2.  EXACTLY:

父节点使用这种模式来强制设定子节点的精确尺寸,子节点必须使用这个尺寸,并且保证它的所有的子节点都适应这个尺寸。

3.  AT_MOST:

父节点使用这种模式强制子节点使用最大的尺寸。字节点必须保证它和它的所有的子节点都适应这个尺寸。

你可能感兴趣的:(框架,android,layout)