Android必会基础之Android是如何绘制视图的

        当Acticity接收到焦点后, 它会请求绘制布局。Android框架负责处理绘制的过程,但Activity必须提供布局层次的根节点。

        绘制从布局的根节点处开始。它被请求度量和绘制布局树。绘制会在树中游走并在无效区域渲染视图。依次的,每个视图组负责请求每个子视图绘制(用draw()方法),每个视图负责绘制自身。因为这个树是按一定顺序生长的,所以父视图会比它们的孩子视图先(或后)绘制,兄弟视图之间就按照它们在树中出现的顺序来绘制。

注:框架不会在无效区域(invalid region)以外的地方绘制视图,并且在后台小心翼翼的为你绘制。你可以强制绘制视图,调用invalidate().

Linc注:这个无效区域是什么意思,我在网上搜了一下,并没用明确的答案,希望有知道的大侠可以告知。上面的意思是只能在这个区域绘制视图。那么是不是就可以这样理解,这个区域是专门用来绘制视图的区域?那么如何获得呢?

        绘制布局要分为两个过程:度量和布局。度量(measuring)调用measure(int, int)方法来实现并且它也是从上到下遍历视图树。每个视图在递归的时候从树上向下依次度量它的尺寸。在度量的最后,每个视图都会存储它的度量值。第二个过程也是从上到下,调用layout(int, int,int, int)来进行。在这个过程每个父亲视图负责用度量阶段计算的大小值来定位(配置)它们的孩子视图。

        当视图的measure方法返回时,必须要设置它们的getMeasuredWidth()和getMeasuredHeight()的值及所有它们的子节点(descendants)。一个视图度量的宽和高的值必须要遵守它的父亲视图的约束,并不是随意设定的。这样就保证在度量的最后,每个父亲都接受它们的孩子的度量值。一个父亲视图可能不止一次的在其孩子上调用measure()方法。举个例子,父亲在没有找到它们想要的度量值时,如果孩子的度量值的和太大或太小,会再次调用measure度量每个孩子(如果孩子不同意它们获得的空间时,父亲将会介入(intervene)并在第二阶段设置规定)。

注:初始化布局,要调用requestLayout()。在视图确信在当前边界已不再适合时调用此方法。

        度量阶段使用两个类来交流视图的大小。View.MeasureSpec类是视图用来告知它们的父亲它们想要度量和定位的。LayoutParams基类只是描述视图想要它的宽和高到底多大。对每个尺寸,它可以指定下面的其中一个:

1、  一个确切值

2、  FILL_PARENT,这意味着它想和父亲一样大小

3、  WRAP_CONTENT,这意味着它只想要能满足自己的内容的大小

        对不同的ViewGroup的子类都会有相应的LayoutParams子类。例如,RelativeLayout有自己的LayoutParams子类,它包含设置子视图在水平和垂直中央的能力。

MeasureSpecs用来从树上到树下发送请求给父视图及子视图。MeasureSpec可以是下面三种模式的一种:

1、  UNSPECIFIED:

子视图可以自己确定大小。例如,LinearLayout可能调用measure()方法在子视图的高设置UNSPECIFIED和宽为EXACTLY240时,子视图的高可以自己设定,宽为240像素。

2、  EXACTLY:

父视图强制为子视图设置一个值,子视图必须使用这个大小并且其后代视图一定要在这个值的范围内。

3、  AT_MOST:

父视图为子视图设置一个最大值。子视图必须要遵守它和它的后代视图的大小都在最大值以内。

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