【问题标题】:How to clip a circular path inside a rectangle in Android如何在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);

标签: android android-4.0-ice-cream-sandwich ondraw clipping custom-draw


【解决方案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 之外应该有一个被覆盖的方法,因为我看到的所有示例都只涉及该方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 2023-03-20
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2020-09-22
    • 2021-03-14
    相关资源
    最近更新 更多