重写方法:
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec);
MeasureSpec类:
MeasureSpec是一个32位的int值,高2位是测量模式,低30位是测量大小。
三种测量模式:
EXACTLY:当给控件的layout_width或layoutt_height属性指定具体数值时,或者match_parent时,系统调用这种模式;
AT_MOST:layout_width或layout_height属性指定为wrap_content时,此时的控件尺寸只要不超过父控件允许的最大尺寸。
UNSPECIFIED:不限制大小,绘制自定义View时使用.
当自定义view需要支持wrap_content时,需要如下重写:
必须实现前三个构造方法
public class MyView extends View { public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec)); } private int measureWidth(int measureSpec){ int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if(specMode==MeasureSpec.EXACTLY){ result = specSize; }else{ result = 200; if(MeasureSpec.AT_MOST==specMode){ result = Math.min(result,specSize); } } return result; } private int measureHeight(int measureSpec){ int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if(specMode==MeasureSpec.EXACTLY){ result = specSize; }else{ result = 200; if(MeasureSpec.AT_MOST==specMode){ result = Math.min(result,specSize); } } return result; } }