2014-01-16 40 views
1

我有一个自定义视图类(称为FooView),我用它作为xml布局的根元素。 FooView,在其onDraw()中,使用canvasFooView的底部边缘绘制形状。调整自定义视图的报告大小以包括绘制图形

我认为,为了FooView不切断形状,我需要重写它的onMeasure并做一些修改报告的身高FooView的,以便它现在包含了拉制形状。

这是正确的吗?如果是这样,我需要做什么?

谢谢!

回答

1

是的,如果您要创建自定义视图,则需要覆盖onMeasure()并提供您需要的大小。

所以,在onMeasure方法签名,你会得到两个参数:

  • widthMeasureSpec
  • heightMeasureSpec

您应该使用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); 
} 
+0

很大的反响!谢谢。只需要添加如果容器视图具有子视图__in addition__到自定义图形(例如,如果容器是'LinearLayout'的子类),则调用'measure()'中的'getMeasuredHeight()'或'getMeasuredWidth() (在调用'super.onMeasure(widthSpec,heightSpec)')之后,只会给出容器的期望维度,而只是提供子视图(而不是自定义图形)。更新容器的所需尺寸以包含自定义绘图,只需添加这些尺寸并用结果调用'setMeasuredDimension()'。 –

+1

不客气。 :)如果它是已经处理测量的ViewGroup的一个子类(如你所说的'LinearLayout'),那么这是真的,但是如果你只是子类'ViewGroup',你必须为你添加的任何子项实现度量和布局。在'ViewGroup'上还有一些helper方法,比如'measureChild()','measureChildren()','measureChildrenWithMargins()'以及类似的东西,以便根据它们的'LayoutParams'轻松测量所有的子视图。 – kcoppock