android view的讲解 之 view的工作流程(measure,layout,draw)(二)
1.view的主要工作流程指:measure测量View的宽高,layout确定View的最终宽高及四个顶点的位置,draw是将view绘制到屏幕上;
1)measure:
测量过程分为两种情况:
view:通过Measure完成测量
viewGroup: 不但通过measure完成自己的测量,还要遍历所有子元素的measure方法,各个元素在递归执行这个流程;
View的测量:
针对measure的onMeasure方法进行查看:
setMeasureDimetion():放置view的宽高测量值
getdefaultSize():返回的大小就是MeasureSpec的SpecSize,这个SpecSize就是view测量后的大小,view的大小最后在layout阶段决定;所以在这里加以区分。(但是最后view的测量大小和最终大小都是相等的)
ViewGroup的测量:
viewGroup是一个抽象类,因此没有重写onMeasure方法,但是提供了一个叫measureChilden的方法,
下边方法是measureChild调用的;
通过上边的源码可以看出,viewGroup在测量时,对每一个子元素进行测量;
3.1测量完成以后,通过getMeasredWidth/Height方法获取view的测量宽高;
4.1在activity启动后获取某个view的宽高:
为什么activity中无法获取到view的宽高;
因为在onCreate()时,view不一定绘制完毕;
解决办法:
1)我们通过onWindowFocuschanged()方法:view已经初始完毕,宽高已经准备好了;
该方法在activity暂停和继续执行任务,窗口失去焦点等情况下会被多次调用;
解决办法:
2) view.post(Runable);
通过post可以将一个runable投递到消息队列的尾部,然后等待Looper调用此runable的时候,view已经初始化好了;
5.1 layout过程
layout作用:viewGroup确定子元素位置,viewGroup确定位置之后,在onLayout遍历所有
子元素view并调用layout方法,layout方法又会调用onLayout方法;
layout大致流程:
通过setFrom方法设定view四个顶点的位置。(mLeft.mRight..)
一旦四个顶点位置确定,那么父容器的位置就确定了,接着调用onLayout方法确定子元素的位置。
LinearLayout中onLayout讲解:
遍历所有子元素调用setChildFrame来确定子元素的位置;通过layout方法调用onLayout方法,
子元素
通过layout方法确定自己的位置,这样一层层传递下去,就是view树的layout过程;
6.1draw过程
draw过程是将view绘制到屏幕上,
view的绘制过程是通过dispathdraw方法传递的,通过dispathDraw遍历所有的draw方法,draw在一层一层的传递下去;