View的measure过程由其measure方法来完成,
measure是一个final类型的方法,不能重写,因此需在measure方法中调用View的
onMeasure方法,在onMeasure方法中又调用
setMeasuredDimension方法来设置View宽/高的测量值,该方法的参数是方法
getDefaultSize(int size,int measureSpec),该方法在specMode为EXACTILY和AT_MOST模式下返回的大小是measureSpec中的specSize,就是View测量后的大小,在UNSPECIFIED模式下返回的size为getSuggestedMinimumWidth/Height()返回的值,该值为:若View没设置背景,返回minWidth属性设置的值,可为0,若有背景,为背景最小宽度与minWidth的最大值。
当自定义的view属性为wrap_content时,需如下重写onMeasure方法,否则wrap_content不生效,为match_parent效果。对于非wrap_content情形,沿用系统的测量值。
ViewGroup的measure过程,ViewGroup是一个抽象类,没有重写View的
onMeasure()方法,但是它提供了一个measureChildren方法,在该方法中又调用了measureChild方法,该方法就是取出子元素的LayoutParams,通过getChildMeasureSpec来创建子元素的MeasureSpec,将之作为参数传给View的measure方法测量。
eg:在Activity启动是获得View的宽高。
(1)在Activity/View的onWindowFoucsChanged方法中获取,此方法在Activity得到和失去焦点时都会被调用。
(2)用View.post(runnable)将runnable投递到消息队尾,等待Looper调用时,View已经初始化好了。
(3)通过ViewTreeObserver。
(4)view.measure()。
Layout的作用是ViewGroup用来确定子元素的位置,当ViewGroup的位置确定后,它在onLayout中会遍历所有的子元素并调用其layout
方法,
在layout中又会调用onLayout方法。layout确定View本身的位置,onLayout会确定子元素的位置。
layout方法的大致流程:通过
setFrame方法设定四个顶点的位置,即确定自己的位置,之后调用
onLayout方法确定子元素的位置,不过onLayout的具体实现和具体的布局有关,所以View和ViewGroup没有真正实现onLayout方法。
View的getMeasureWidth和getWidth方法的区别:默认情况下二者值相等,但getMeasureWidth形成于View的measure过程,而getWidth形成于View的layout过程。
Draw的过程是将View绘制到屏幕上。绘制过程在源码中分为六步,但一般只需四步:1.drawBackground(canvas) 3.onDraw(canvas) 4.dispatchDraw(canvas) (绘制过程的传递)6.onDrawScrollBars(canvas)