无论是在重写view还是viewgroup的时候,尤其是viewgrop的时候,往往不可避免的重写onmeasure方法,我们一定会调用setmeasureddimension()将测量好的宽高值传递进去。也不免调用measurechildren方法,来测量所有的子view的大小,下面我们看看measurechildren方法是如何工作的。这对我们重写onmeasure无疑是很有帮助的。因为一般我们都会看到这一行代码
但是它到底测量到什么程度,满足不满足我们自定义viewgroup对下面一系列child尺寸的测量需求,不知道这个我们写代码就心里没底。所以我们有必要扒出它的老底来看看,由此来决定我们是否可以直接使用这个方法,还是由于我们有更多的效果要实现,有更多的因素需要考虑,这个方法不能满足需求,需要自己写方法来测量child。
同时我们在有必要重新写方法来测量child的时候,我们也要从自带方法的思路开始扩展。
说了一大堆,总之这个问题很重要。
下面要了解它的工作原理,我们还是要来看看源码:
(一)首先是measurechildren
这部分很简单,也就是遍历所有的子view,如果view的状态不是gone就调用measurechild去进行下一步的测量。
(二)所以我们再来看一下measurechild
*/ protected void measurechild(view child, int parentwidthmeasurespec, int parentheightmeasurespec) { // 取得子视图的布局参数 final layoutparams lp = child.getlayoutparams(); // 通过getchildmeasurespec获取最终的宽高详细测量值 final int childwidthmeasurespec = getchildmeasurespec(parentwidthmeasurespec,
mpaddingleft + mpaddingright, lp.width); final int childheightmeasurespec = getchildmeasurespec(parentheightmeasurespec, mpaddingtop + mpaddingbottom, lp.height); // 将计算好的宽高详细测量值传入measure方法,完成最后的测量 child.measure(childwidthmeasurespec, childheightmeasurespec);
}
这个方法就是对一个子视图进行测量,其中一个重要的方法就是getchildmeasurespec(),
(三)所以我们再来看一下getchildmeasurespec
总而言之,这些判断和设置其实就是根据三种模式以及传入的尺寸要求,还有需要考虑的padding和margin之后,比较全面的计算出了一个测量值,了解了这些之后我们就可以确定什么时候需要自己写关于子视图的测量部分,什么时候我们只需要简单的一行代码:
就可以满足我们的需求了,所以一切还是按需来处理。
在我个人看来,这个方法考虑的比我最初想象的要全面多了,看来除了有比较特殊的需求,大部分的时候都是可以直接使用这个方法的。这还是省了不少事的。
如果您对我提到的模式或者是重写过程不大了解的,具体的关于重写onmeasure内容请详见我的另外一篇博客:
http://blog.csdn.net/sunmc1204953974/article/details/38454267
希望大家能有所收获,我也是学生,有什么写的不好的地方还请多多指教!