2015-04-05 20 views
2

Я прочитал более 20 вопросов/ответов, но я все еще не могу получить то, что хочу. Я хочу, чтобы вырезать круг внутри прямоугольника, как показано ниже:Как скопировать круговой путь внутри прямоугольника в Android

enter image description here

Вот мой код: не

@Override 
protected void onDraw(Canvas canvas) { 
    Paint paint = new Paint(); 
    paint.setStyle(Paint.Style.FILL); 
    paint.setARGB(180, 0, 0, 0); 
    canvas.drawRect(0, 0, getWidth(), getHeight(), paint); 
    Path circularPath = new Path(); 
    circularPath.addCircle(getWidth()/2, getHeight()/2, radius, Path.Direction.CCW); 
    canvas.clipPath(circularPath, Region.Op.REPLACE); 
    canvas.drawColor(0x00000000); 


} 

Мой фон (setARGB) отображается корректно, однако ничего обрезается. Я также пробовал разные значения Op, отличные от REPLACE, принудительное растрирование программного обеспечения (как я читал на некоторых версиях Android clipPath, не поддерживает некоторые из Op s), вызывая setLayerType(LAYER_TYPE_SOFTWARE, null); на конструкторе, но безрезультатно. Как достичь желаемого эффекта?

Примечание: Минимальная версия SDK - 15, поэтому мне не нужно поддерживать что-либо ниже 4.0.

+0

вы пытались Region.Op.DIFFERENCE? – pskink

+0

@pskink да, просто попробовал снова, чтобы убедиться. К сожалению, ничего не происходит. –

+0

DIFFERENCE просто отлично работает для меня, попробуйте canvas.drawColor с Color.RED, затем clipPath, а затем drawColor 0x88000000 – pskink

ответ

1

Попробуйте отсечение свой путь в dispatchDraw():

@Override 
protected void dispatchDraw(Canvas canvas) 
{ 
    canvas.clipPath(mClipPath, mRegion); // previously created path & region 

    super.dispatchDraw(canvas); 
} 

Удалите отсеченной код из метода onDraw, и что должен сделать это.

Edit:

При создании пути, убедитесь, что вы это только после того, как произошло измерение, например:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{ 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    mClipPath.reset(); 
    float radius = Math.min((float)getMeasuredWidth()/2f, (float)getMeasuredHeight()/2f) + 5; 
    mClipPath.addCircle((float)getMeasuredWidth()/2f, (float)getMeasuredHeight()/2f, radius, Path.Direction.CCW); 
} 
+0

Пробовал, ничего не менял. –

+0

Я отредактировал свой ответ, чтобы включить возможную причину того, почему он не работает для вас –

+2

Скопируйте/вставьте его. Все равно никаких изменений. Я очень сомневаюсь, что должен быть переопределенный метод, отличный от 'onDraw', поскольку все примеры, которые я видел, включают только этот метод. –