自定义 View:resolveSizeAndState 方法
发布于: 刚刚
1.知识点
期望尺寸
实际尺寸
draw:总调度,调用 onDraw
measure:总调度,调用 onMeasure,
layout:执行具体的操作
onLayout:传递给子 View
2.原理
/**
* Utility to reconcile a desired size and state, with constraints imposed
* by a MeasureSpec. Will take the desired size, unless a different size
* is imposed by the constraints. The returned value is a compound integer,
* with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
* optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the
* resulting size is smaller than the size the view wants to be.
*
* @param size How big the view wants to be.
* @param measureSpec Constraints imposed by the parent.
* @param childMeasuredState Size information bit mask for the view's
* children.
* @return Size information bit mask as defined by
* {@link #MEASURED_SIZE_MASK} and
* {@link #MEASURED_STATE_TOO_SMALL}.
*/
public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
final int specMode = MeasureSpec.getMode(measureSpec);
final int specSize = MeasureSpec.getSize(measureSpec);
final int result;
switch (specMode) {
case MeasureSpec.AT_MOST: // 如果mode=AT_MOST,则使用上限
if (specSize < size) { // 如果当前View期望尺寸大于父View允许尺寸,那么返回父View允许尺寸
result = specSize | MEASURED_STATE_TOO_SMALL;
} else { // 否则返回当前View的期望尺寸
result = size;
}
break;
case MeasureSpec.EXACTLY: // 如果mode=EXACTLY,则使用父View指定的尺寸
result = specSize;
break;
case MeasureSpec.UNSPECIFIED:
default:
result = size;
}
return result | (childMeasuredState & MEASURED_STATE_MASK);
}
复制代码
size:当前 View 的期望尺寸
measureSpec:父布局对当前 View 的约束,也就是 开发者想要的在父布局中的位置信息
返回的是 当前 View 的位置信息
3.代码
public class TestView extends View {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
int RADIUS = 800;
int PADDING = 30;
public TestView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GRAY);
canvas.drawCircle(PADDING+RADIUS, PADDING+RADIUS, RADIUS, paint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = (PADDING+RADIUS)*2;
int height = (PADDING+RADIUS)*2;
setMeasuredDimension(width, height);
}
}
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 2
版权声明: 本文为 InfoQ 作者【Changing Lin】的原创文章。
原文链接:【http://xie.infoq.cn/article/4630c9c0499fa0e613d73aadf】。文章转载请联系作者。
Changing Lin
关注
获得机遇的手段远超于固有常规之上~ 2020.04.29 加入
我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。
评论