自定义View首先需要测量View的大小
自定义View
首先需要测量View
的大小,在View
的onMeasure()
方法中进行。
View
的大小分为三种类型,测量模式也有三种
- 自适应(
wrap_content
),对应at_most
(最大值模式),代表的是最大可获得的空间
- 固定(100dp),对应
Exactly
(精确值模式),代表的是精确的尺寸;
- 填充父
View
(match_parent
),对应Exactly
(精确值模式),代表的是精确的尺寸;
- 还有个
UnSpecified
(未指定模式),不指定View
的大小,想多大就多大,用于scrollView
等类。
默认情况
onMeasure()
只支持Exactly
模式,所以要重写onMeasure
方法.
onMeasure
传入的widthMeasureSpec
和heightMeasureSpec
不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值。
MeasureSpec
是一个32位的int
值,高2位为测量模式,低30位为测量的大小。
查看View
的onMeasure()
源码发现,调用了setMeasuredDimension(int measuredWidth, int measuredHeight)
方法。
那么我们只要将设置好的长宽参数穿进去即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.i("onMeasure","onMeasure"); setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
} private int measureWidth(int measureSpec) { int result; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec);
Log.i("measureWidth","specSize:"+specSize); if(specMode == MeasureSpec.EXACTLY){ Log.i("measureWidth","specMode:"+"MeasureSpec.EXACTLY"); result = specSize; } else { result = 200; if(specMode == MeasureSpec.AT_MOST){ Log.i("measureWidth","specMode:"+"MeasureSpec.AT_MOST"); result = Math.min(result, specSize); } else if(specMode == MeasureSpec.UNSPECIFIED){ Log.i("measureWidth","specMode:"+"MeasureSpec.UNSPECIFIED"); } } return result; }
|
onMeasure()触发了两次?
打印log时出现这个问题,待解决