onMeasure()
是您告诉Android您希望自定义视图多大取决于父级提供的布局约束的机会;这也是您自定义视图的机会,以了解这些布局约束是什么(以防您希望在某种match_parent
情况下与其他wrap_content
情况有所不同)。这些约束打包成MeasureSpec
传递给方法的值。这是模式值的粗略相关:
- 完全表示将
layout_width
或layout_height
值设置为特定值。您可能应该使视图大小如此。match_parent
使用时也会触发此事件,以将尺寸精确设置为父视图(这在框架中取决于布局)。
- AT_MOST通常意味着将
layout_width
or layout_height
值设置为match_parent
或wrap_content
需要最大大小的位置(这是框架中的布局所决定),而父维度的大小就是该值。您的大小不得超过此大小。
- “未指定”通常表示将
layout_width
或layout_height
值设置为wrap_content
无限制。您可以选择任何大小。一些布局还使用此回调函数来确定所需的大小,然后再确定要在第二个度量请求中再次实际通过您的规格。
与存在的合同onMeasure()
是setMeasuredDimension()
必须在与大小结束时调用你想的观点是。所有框架实现都调用此方法,包括在中找到的默认实现View
,这就是为什么在super
适合您的用例的情况下可以安全地进行调用的原因。
当然,因为框架确实应用了默认实现,所以您不一定需要重写此方法,但是如果视图空间小于内容而不是内容并且您对布局进行了布局,则可能会看到裁剪。wrap_content
双向的自定义视图,您的视图可能根本无法显示,因为框架不知道它的大小!
通常,如果您要重写View
而不是其他现有的小部件,则提供实现是一个好主意,即使它像这样简单:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = 100;
int desiredHeight = 100;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
希望对您有所帮助。