1、onMeasure什么时候回被调用?
onMeasure方法的作用:测量控件的大小。当创建一个View的时候不需要测量这个控件的大小,只有将这个View放入到一个容器(父控件)中的时候才需要去测,而这个测量的方法就是父控件唤起调用的。当控件的父控件要放置这个子控件的时候,父控件会调用子控件的onMeasure方法询问子控件“你需要多大的尺寸啊?”,然后传入两个参数:
widthMeasureSpec、heightMeasureSpec。这两个参数是父控件告诉子控件可获得的控件以及这个控件的约束条件,子控件拿到这个条件就能正确的测量自身的宽高了。
2、MeasureSpec类
2.1说明:
MeasureSpec约束是由父控件传递给子控件的。这个类的组成:测量规则(MeasureSpec)= 测量模式(mode)+ 测量大小(size)。而其中的测量模式有 3 种类型:
2.2 MeasureSpec如何计算
结论:子View的MeasureSpec值是根据 子View的布局参数(LayoutParams) 和 父控件的MeasureSpec值计算出来的。换句话说就是:子 View 的大小由 父View 的MeasureSpec值 和 子View 的LayoutParams属性决定。
3、 Measure过程
measure的过程主要根据View的类型分为两种情况:单个View(即只要测量自身的一个View) 和 ViewGroup(对ViewGroup视图中所有的子View都进行测量。即遍历调用所有子元素的measure方法 并且 各个子元素再递归去执行该流程)
3.1单个View的measure过程:
measure() --> onMeasure() --> setMeasureDimension() --> getDefaultSize()
总结:
measure() 作用:基本测量逻辑的判断;调用onMeasure()进行下一步测量;
onMeasure() 作用:1、根据对宽高的 测量规则(MeasureSpec)计算View的宽高值:getDefaultSize(); 2、储存测量后的子View宽高 setMeasureDimension
getDefaultSize() 作用:根据View的宽高测量规则计算View的宽高值
setMeasureDimension() 作用:存储测量后的子View的宽高
3.2 ViewGroup的measure过程
流程:measure() --> onMeasure() --> measureChildren() --> measureChild() --> getChildMeasureSpec() -->遍历子View测量 & 合并 -->setMeasureDimension()
注意接下来的 onMeasure 是针对ViewGroup中的所有子View来讲的? 因为ViewGroup是一个抽象类,无法重写View的onMeasure()
根据上面总结:ViewGroup无法对onMeasure()作出统一的实现。这个也是ViewGroup的measure的过程与单一的Viewmeasure过程的最大不同。
接下来我们需要 覆写 onMeasure()方法:
总结:从上面可以看出,覆写onMeasure()方法有 3 步,其中第2步直接调用系统方法(在这个方法measureCarson()中需要合并所有的子View的尺寸)。
接下来分析 measureChildren():
这样ViewGroup的measure过程就说完了。