view的绘制流程
view的绘制流程分为mesure、layout和draw三个阶段,measure是对view宽和高进行测量,确定了view的measuredwidht和measuredheight,layout是对view进行布局,确定了view四个顶点的位置,draw是将view绘制在屏幕之上。
1、Measure,
View的measure要分为两种情况来说:
1.1、非容器 view,它的 measure 过程比较简单,就是在其 onmeasure方法中根据父view传递过来的measurespec和自身的情况来得到其自身的宽和高,然后通过 setmeasureddimension去设置这个宽和高。
1.2、对于viewgroup的 measure过程,viewgroup的测量,不但要在 onmeasure要完成自身的测量,还要完成对它其中的子元素的测量, 因为,各种 viewgroup的布局不同,所以测量的细节也不同,因此, viewgroup中没有具体实现 onmeasure方法,而是让子类自己去实现。
viewgroup子类实现 onmeasure的一般过程是调用 measurechildren去测量子元素,measurechildren中会遍历出所有的子元素,然后依次调用 measurechild方法去对每一个 子元素进行测量,在 measurechild中会调用 getchildmeasurespec 通过父容器的 measurespec和子元素的 layoutparams,pading等得 到子元素的 measurespec,然后调用子元素的 measure方法,将刚才得到的子元素的 measurespec传递给子元素的 measure方法,让子元 素自己去完成自身的测量,这样就将测量的过程从父容器传递到子元素中去了,当所有子元素测量完毕之后,父容器还要根据子元素的测量情况, 来测量自身的大小。例如LinearLayout的测量过程中就会维护一个totallength的变量,每测量一个子元素,totallength就会加上这个子元素的高度或者宽度,最后LinearLayout会根据这个变量通过setmeasureddimension去设置自己的宽高。
2、Layout
view的layout过程也分为两种情况:
2.1、非容器view的,它的layout过程也比较简单,就是在其layout方法中根据父view传递过来的四个顶点的位置结合自身情况来得到自身四个顶点的位置,然后调用setframe对这个四个顶点的值进行设置。
2.2、viewgroup的layout过程首先也是在layout方法中根据父view传递过来的四个顶点的位置结合自身情况来得到自身四个顶点的位置,然后也是调用setframe对这个四个顶点的值进行赋值。然后它还要去遍历它其中所有的子元素,根据自身的位置和子元素的measure过程中得到宽高以及gravity等一些参数来得到子元素的四个顶点的位置,然后调用子元素的layout方法将得到的子元素的四个顶点的位置传递子元素的layout过程中去,子元素就可以按这个四个顶点的位置对自身进行布局。
3、Draw
Draw过程就相对简单,view的 draw方法中主要通过 4步去绘制一个 view,第一步通过 drawbackgroud去绘制 view的背景,第二步通过 ondraw去绘制 view自身,第三步,如果它是一个viewgroup的话,就会通过 dispatchdraw遍历所有的子元 素,然后调用子元素的 draw方法,将绘制的流程传递到子元素中去, 如果它是一个非容器view的话,它就会跳过这一步,第四步,通过 ondrawscrolbars绘制装饰。
网友评论