前端时间又看了些自定义控件的小demo,但是要知道demo始终是demo,只是用来做某个功能的演示或讲解的,所以我发现多数将自定义控件的demo就是没有关注在实际使用中这个控件合适的大小问题,很多demo都是不管写什么控件,控件的画布大小都是整个屏幕,然后把控件放在画布中间。所以,在实际开发中,或者你想自定义一个供别人使用的控件,那么还是应该关注怎么确定控件的大小。
自定义控件中与控件大小相关的几个方法
1、控件的测量
/** * 这里是确定控件的大小的方法 * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); }2、控件大小确定
/** * 这里可以得到控件的最终大小 * @param w * @param h * @param oldw * @param oldh */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); }我们可以通过以上方法设定控件的大小并最终得到相关的尺寸。
设置自定义控件大小的标准做法
如何确定控件的大小呢?正确的做法是:控件应该有一个默认的合适的大小,当我们在layout布局文件里面使用这个控件,并设置这个控件的宽高属性都是wrap_content的时候,或者我们直接调用这个控件的构造方法实例化这个控件,并且没有设置控件的大小的时候,这个控件就应该使用默认的尺寸;而当我们在使用这个控件的时候为这个控件设定了指定的大小的时候,控件就应该使用指定的大小。
下面看一段代码:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measure(widthMeasureSpec, true), measure(heightMeasureSpec, false)); } @Override protected int getSuggestedMinimumWidth() { return (int) (defaultEdgeDis*(defaultEdgeNum - 1) + defaultLineWidth*defaultEdgeNum + defaultRadius); } @Override protected int getSuggestedMinimumHeight() { return (int) (defaultEdgeDis*(defaultEdgeNum - 1) + defaultLineWidth*defaultEdgeNum + defaultRadius); } private int measure(int measureSpec, boolean isWidth){ int result; int size = MeasureSpec.getSize(measureSpec); int mode = MeasureSpec.getMode(measureSpec); int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom(); if (mode == MeasureSpec.EXACTLY){//表示用户设定了大小 result = size; } else { result = isWidth ? getSuggestedMinimumWidth() : getSuggestedMinimumHeight(); result += padding; if (mode == MeasureSpec.AT_MOST){ result = Math.max(result, size); } } return result; }首先通过在onMeasure方法中,调用setMeasureDimension方法设置控件的大小, 注意不要再调用super.onMeasure方法,在这个方法中我们自定义了一个measure的方法,在此方法中我们分别设置控件的宽度和高度,如果控件在layout布局中指定了控件的大小(不是wrap_content),此时我们获取的mode为MeasureSpec.EXACTLY,直接将控件的宽高设置成在布局中指定的大小;否则,我们会根据getSuggestedMinimunWidth和getSuggestedMinimunHeight方法分别设定控件的大小,也就是我们自己设置的控件的默认的合适的大小。嗯,接下来就是控件的绘制了,这个demo还在写,后面加上源码地址!