Android View.MeasureSpec
有时,Android系统控件无法满足我们的需求,因此有必要自定义View。
一般来说,自定义控件都会去重写View的onMeasure方法,因为该方法指定该控件在屏幕上的大小,【protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)】。
onMeasure传入的两个参数是由上一层控件传入的大小,有多种情况,重写该方法时需要计算控件的实际大小,然后调用setMeasuredDimension(int, int)设置实际大小。
onMeasure传入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值,我们需要通过int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。
MeasureSpec由大小(size)和模式(model)组成,mode共有三种情况,取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。
MeasureSpec.EXACTLY 是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width="50dip",或者为FILL_PARENT时,都是控件大小已经确定的情况,都是精确尺寸。
MeasureSpec.AT_MOST 是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可,因此此时的mode是AT_MOST,size给出了父控件允许的最大尺寸,子空间可以进行变大但不能超过最大尺寸。
MeasureSpec.UNSPECIFIED 是父layout不限制它子元素的大小,可以设置成任意大小,比如父容器为ScrollView。