我有一个自定义视图类(称为FooView
),我用它作为xml布局的根元素。 FooView
,在其onDraw()
中,使用canvas
在FooView
的底部边缘绘制形状。调整自定义视图的报告大小以包括绘制图形
我认为,为了FooView
不切断形状,我需要重写它的onMeasure
并做一些修改报告的身高FooView
的,以便它现在包含了拉制形状。
这是正确的吗?如果是这样,我需要做什么?
谢谢!
我有一个自定义视图类(称为FooView
),我用它作为xml布局的根元素。 FooView
,在其onDraw()
中,使用canvas
在FooView
的底部边缘绘制形状。调整自定义视图的报告大小以包括绘制图形
我认为,为了FooView
不切断形状,我需要重写它的onMeasure
并做一些修改报告的身高FooView
的,以便它现在包含了拉制形状。
这是正确的吗?如果是这样,我需要做什么?
谢谢!
是的,如果您要创建自定义视图,则需要覆盖onMeasure()
并提供您需要的大小。
所以,在onMeasure
方法签名,你会得到两个参数:
您应该使用MeasureSpec
类来获得你应该尊重限制在确定视图大小时。
/*
* This will be one of MeasureSpec.EXACTLY, MeasureSpec.AT_MOST,
* or MeasureSpec.UNSPECIFIED
*/
int mode = MeasureSpec.getMode(measureSpec);
//This will be a dimension in pixels
int pixelSize = MeasureSpec.getSize(measureSpec);
如果你MeasureSpec.EXACTLY
,那么你应该使用pixelSize
值的测量宽度,不管是什么。
如果您得到MeasureSpec.AT_MOST
,则应确保将测量宽度设置为不大于pixelSize
。
如果您获得MeasureSpec.UNSPECIFIED
,您可以根据需要占用足够的空间。我通常只是将其解释为WRAP_CONTENT
。
所以你onMeasure()
方法可能是这个样子:
@Override
protected void onMeasure (int widthSpec, int heightSpec) {
int wMode = MeasureSpec.getMode(widthSpec);
int hMode = MeasureSpec.getMode(heightSpec);
int wSize = MeasureSpec.getSize(widthSpec);
int hSize = MeasureSpec.getSize(heightSpec);
int measuredWidth = 0;
int measuredHeight = 0;
if (wMode == MeasureSpec.EXACTLY) {
measuredWidth = wSize;
} else {
//Calculate how many pixels width you need to draw your View properly
measuredWidth = calculateDesiredWidth();
if (wMode == MeasureSpec.AT_MOST) {
measuredWidth = Math.min(measuredWidth, wSize);
}
}
if (hMode == MeasureSpec.EXACTLY) {
measuredHeight = hSize;
} else {
//Calculate how many pixels height you need to draw your View properly
measuredHeight = calculateDesiredHeight();
if (hMode == MeasureSpec.AT_MOST) {
measuredHeight = Math.min(measuredHeight, hSize);
}
}
setMeasuredDimension(measuredWidth, measuredHeight);
}
很大的反响!谢谢。只需要添加如果容器视图具有子视图__in addition__到自定义图形(例如,如果容器是'LinearLayout'的子类),则调用'measure()'中的'getMeasuredHeight()'或'getMeasuredWidth() (在调用'super.onMeasure(widthSpec,heightSpec)')之后,只会给出容器的期望维度,而只是提供子视图(而不是自定义图形)。更新容器的所需尺寸以包含自定义绘图,只需添加这些尺寸并用结果调用'setMeasuredDimension()'。 –
不客气。 :)如果它是已经处理测量的ViewGroup的一个子类(如你所说的'LinearLayout'),那么这是真的,但是如果你只是子类'ViewGroup',你必须为你添加的任何子项实现度量和布局。在'ViewGroup'上还有一些helper方法,比如'measureChild()','measureChildren()','measureChildrenWithMargins()'以及类似的东西,以便根据它们的'LayoutParams'轻松测量所有的子视图。 – kcoppock