1.什么是布局过程
布局是计算控件大小和位置的过程。
布局过程分为两个阶段
- 测量阶段
根据子控件的大小和ViewGroup自身的布局规则,确定ViewGroup自身的大小 - 布局阶段
根据子控件大小和自身的布局规则,确定子控件的位置
2.测量和布局阶段原理总览
3.测量阶段的原理细讲
父容器在onMeasure方法中先测量出child的尺寸,然后再测量出自己的尺寸
以AbsoluteLayout为例
-
调用ViewGroup.measureChildren()测量所有child的尺寸
测量好后child会调用setMeasuredDimension保存测量的尺寸,
然后可以通过child的view.getMeasuredWidth获取测量的尺寸。ViewGroup.getChildMeasureSpec函数很关键(承上启下的作用)
getChildMeasureSpec(int spec, int padding, int childDimension)
根据ViewGroup的parentWidthMeasureSpec,Child的widthMeasureSpec计出Child的最终的widthMeasureSpe 根据child测量得到的尺寸计算得到AbsoluteLayout最大的尺寸
根据计算得到的maxWidth,自己的withMeasureSpec,得到自己的尺寸,并保存。
4. 要重写onMeausre的一些情况
- 对高宽有特殊的要求,比如:要求高一定要和宽一样大
- 继承View的视图中要绘制多个内容
如下,自定义的View继承View,并且要绘制一个图片和文字,这是需要重写onMeasure,
- 自定义视图的宽=Bitmap.widh+文字.width
-
自定义视图的高=max(Bitmap.height,文字.height)
5.总结
- 尺寸由尺寸模式和尺寸大小组成?
因为控件的尺寸大小不是由自己决定的,还要考虑到父容器的大小。- AT_MOST 控件最大大小不能超过指定大小
- EXACTLY 控件大小为指定的大小
- UNSPECIAl 不对控件大小进行约束
- 调用ViewGroup.measureChildren()测量所有child的尺寸 ,
然后child会调用view.setMeasuredDimension保存测量的尺寸,
然后通过child的view.getMeasuredWidth获取测量的尺寸。 - ViewGroup.getChildMeasureSpec函数很关键
getChildMeasureSpec(int spec, int padding, int childDimension)
根据ViewGroup的parentWidthMeasureSpec,Child的widthMeasureSpec计出Child的最终的widthMeasureSpec - 如果想手动测量某个View的尺寸
调用View.measure()方法