Android 使用clipRect - 解释

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3331805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:46:44  来源:igfitidea点击:

Using clipRect - explanation

androidandroid-canvasandroid-view

提问by Namratha

public class POCII extends Activity { 

    myView mv = new myView(this); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(mv); 
    }
}


class myView extends View { 

    public myView(Context context) { 
       super(context); 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 

        Paint paint = new Paint(); 

        canvas.drawRect(0,0,100,100, paint); 
        canvas.clipRect(0,0,50,50);
    } 
}

My question is, shouldn't the above code draw a rectangle and then crop the top left portion? The rectangle is not getting cropped.

我的问题是,上面的代码不应该画一个矩形然后裁剪左上角吗?矩形没有被裁剪。

Please explain what clipRect does. What is it actually clipping? Does it clip in the form of a rectangle, given the co-ordinates? If so, Why is the above code not working?

请解释一下 clipRect 的作用。它实际上在剪辑什么?给定坐标,它是否以矩形的形式剪辑?如果是这样,为什么上面的代码不起作用?

回答by Ribo

Canvas.clipRect(left, top, right, bottom)reduces the region of the screen that future draw operations can write to. It sets the clipBounds to be the spacial intersection of the current clipping rectangle and the rectangle specified. There are lot of variants of the clipRect method that accept different forms for regions and allow different operations on the clipping rectangle. If you want to explicitly set the clipping region, try:

Canvas.clipRect(left, top, right, bottom)减少未来绘制操作可以写入的屏幕区域。它将clipBounds 设置为当前裁剪矩形和指定矩形的空间交点。clipRect 方法有很多变体,它们接受不同的区域形式并允许对裁剪矩形进行不同的操作。如果要明确设置剪切区域,请尝试:

canvas.clipRect(left, top, right, bottom, Region.Op.REPLACE);

The 5th argument means replace the clipping rectangle rather than creating the intersection with the previous version.

第 5 个参数表示替换剪切矩形而不是创建与先前版本的交集。

Try moving the clipRect statement before the drawRect statement. Or, try adding:

尝试在 drawRect 语句之前移动 clipRect 语句。或者,尝试添加:

paint.setColor(Color.YELLOW);
drawRect(0,0,75,75);

after your existing clipRect statement. It should draw a 50x50 yellow square over what you had before.

在您现有的 clipRect 语句之后。它应该在你之前画一个 50x50 的黄色方块。

Another note: (after long frustration with the apparently, largely undocumented View/ViewGroup/drawing code) I found that canvas.translate(x,y) also adjusts the clipRect. The interaction of clipRect and the drawing matrix is very confusing. It is helpful to print out:

另一个注意事项:(在对显然没有记录的 View/ViewGroup/drawing 代码长期感到沮丧之后)我发现 canvas.translate(x,y) 也调整了 clipRect。clipRect 和绘制矩阵的交互非常混乱。打印出来很有帮助:

canvas.getMatrix()

and

canvas.getClipBounds()

before and after modifications to the canvas and before drawing things.

在修改画布之前和之后以及在绘制事物之前。

回答by Matt Hansen

To crop the top left portion, do:

要裁剪左上部分,请执行以下操作:

canvas.clipRect(0,0,50,50, Region.Op.DIFFERENCE);
// secondly...
canvas.drawRect(0,0,100,100, paint); 

回答by SHS

ICS and above ...

ICS及以上...

XOR, Difference and ReverseDifference clip modes are ignored by ICS if hardware acceleration is enabled.

Just disable 2D hardware acceleration in your view:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

如果启用硬件加速,ICS 将忽略 XOR、Difference 和 ReverseDifference 剪辑模式。

只需在您的视图中禁用 2D 硬件加速:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Reference Android: Howto use clipRect in API15

参考Android:如何在API15中使用clipRect

回答by j2emanue

your drawing looks like this without using cliprect:

不使用 cliprect 时,您的绘图如下所示:

enter image description here

在此处输入图片说明

now if we use a cliprect we are putting a overlay of a rectange over what we already have. its sort of invisible. lets say we called the following:

现在,如果我们使用 cliprect,我们将在已有的矩形上叠加一个矩形。它是无形的。假设我们调用了以下内容:

 override fun onDraw(canvas: Canvas) {

        val paint =  Paint();
        paint.color = Color.RED
        canvas.clipRect(0f,0f,500f,500f, Region.Op.DIFFERENCE);
// secondly...
        canvas.drawRect(0f,0f,1000f,1000f, paint);
    }

since we use DIFFERENCE option and we know the clipping rectangle is now OVER our canvas red rectangle we can tell me special things. above says we should KEEP the DIFFERENCE between the clipping rectangle and the original. so it will look like this (since i used half of 1000 for clipping rectangle):

因为我们使用了 DIFFERENCE 选项并且我们知道裁剪矩形现在在我们的画布红色矩形上方,所以我们可以告诉我一些特别的事情。上面说我们应该保持剪切矩形和原始矩形之间的差异。所以它看起来像这样(因为我用了 1000 的一半来裁剪矩形):

enter image description here

在此处输入图片说明

and the oppositeif we used intersect would look like this: enter image description here

相反的,如果我们使用的交叉是这样的: 在此处输入图片说明

i'd love to see if someone can make it do rounded corners.

我很想看看是否有人可以让它做圆角。