onMeasure方法中使用resolveSizeAndState,支持2.2
自定义View一般需要重写onMeasure方法,根据不同的需求onMeasure的实现也不同,如果你的View不是非常特别,都可以参考谷歌官方文档中对onMeasure的实现:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Try for a width based on our minimum
int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
int w = resolveSizeAndState(minw, widthMeasureSpec, 1);
// Whatever the width ends up being, ask for a height that would let the pie
// get as big as it can
int minh = MeasureSpec.getSize(w) - (int)mTextWidth + getPaddingBottom() + getPaddingTop();
int h = resolveSizeAndState(MeasureSpec.getSize(w) - (int)mTextWidth, heightMeasureSpec, 0);
setMeasuredDimension(w, h);
}
resolveSizeAndState
()可以使你的view更像一个控件,之前一直都是按照自己的想法写onmeasure,有时出现大小跟预期的不一致,后来看了官方文档,试着把resolveSizeAndState
方法运用进去,发现大小变得正常了,但是其中的resolveSizeAndState
方法在新的api中才有,无法兼容3.0以下。
不就是个方法而已嘛,虽然api不支持,但是可以自己写啊,感觉其实现的代码也不会太多。
本来想自己写的,但是在stackoverflow上看到了别人的实现方法,一下懒了,还是吃现成吧,为了不和api的方法名冲突,我们改为resolveSizeAndState2:
private int resolveSizeAndState2(int size, int measureSpec, int childMeasuredState) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
if (specSize < size) {
result = specSize | MEASURED_STATE_TOO_SMALL;
} else {
result = size;
}
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result | (childMeasuredState&MEASURED_STATE_MASK);
}