如何在Android中剪切矩形内的圆形路径

Posted

技术标签:

【中文标题】如何在Android中剪切矩形内的圆形路径【英文标题】:How to clip a circular path inside a rectangle in Android 【发布时间】:2015-06-10 01:56:26 【问题描述】:

我已经阅读了 20 多个问题/答案,但我仍然无法得到我想要的。我想在一个矩形内切一个圆,如下所示:

这是我的代码:

@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) 显示正确,但没有任何内容被剪裁。除了REPLACE,我还尝试了不同的Op 值,通过调用setLayerType(LAYER_TYPE_SOFTWARE, null); 强制软件光栅化(正如我在某些android 版本上阅读的clipPath 不支持某些Ops)构造函数,但无济于事。如何达到预期的效果?

注意:我的最低 SDK 版本是 15,所以我不需要支持低于 4.0 的任何东西。

【问题讨论】:

您尝试过 Region.Op.DIFFERENCE 吗? @pskink 是的,现在再次尝试确认。不幸的是,什么也没发生。 DIFFERENCE 对我来说效果很好,尝试使用 Color.RED 使用 canvas.drawColor,然后使用 clipPath,然后使用 drawColor 0x88000000 @pskink 你能发布一个 sscce 作为答案吗? 就这样使用:canvas.drawColor(Color.RED);路径循环路径 = 新路径(); circularPath.addCircle(getWidth() / 2, getHeight() / 2, 300, Path.Direction.CCW); canvas.clipPath(循环路径,Region.Op.DIFFERENCE); canvas.drawColor(0x66000000); 【参考方案1】:

drawRect 之前使用clipPath

@Override
protected void onDraw(Canvas canvas) 
    super.onDraw(canvas);

    int width = this.getWidth();
    int height = this.getHeight();

    mPaint.setAntiAlias(true);
    mPaint.setColor(Color.WHITE);
    mPaint.setStyle(Paint.Style.FILL);
    canvas.drawPaint(mPaint);

    float rectWidth = Utils.dpToPx(100.0f);

    Path circularPath = new Path();
    circularPath.addCircle(width / 2.0f, rectWidth / 2.0f, rectWidth / 3.0f, Path.Direction.CCW);
    canvas.clipPath(circularPath, Region.Op.DIFFERENCE);

    mPaint.setColor(Color.BLUE);
    canvas.drawRect((width - rectWidth) / 2.0f, 0.0f, ((width - rectWidth) / 2.0f) + rectWidth, rectWidth, mPaint);

【讨论】:

【参考方案2】:

尝试在dispatchDraw() 中剪裁路径:

@Override
protected void dispatchDraw(Canvas canvas)

    canvas.clipPath(mClipPath, mRegion); // previously created path & region

    super.dispatchDraw(canvas);

从您的onDraw 方法中删除路径剪辑代码,这样就可以了。

编辑:

创建路径时,请确保仅在测量发生后才这样做,例如:

@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);

【讨论】:

试过了,没什么变化。 我已经编辑了我的答案,以包括为什么它不适合你的可能原因 复制/粘贴它。还是没有变化。我非常怀疑除了onDraw 之外应该有一个被覆盖的方法,因为我看到的所有示例都只涉及该方法。

以上是关于如何在Android中剪切矩形内的圆形路径的主要内容,如果未能解决你的问题,请参考以下文章

如何在圆形 imageView android 上添加一个阴影和边界

在 FabricJS 中调整窗口大小时如何始终将剪切区域居中?

如何在矩形 div 中添加圆形 [重复]

圆圈内的可移动图像

ArcGIS如何从矢量图剪切出一个矩形区域出来?

如何在iOS中实现矩形UIButton到圆形的漂亮动画?