使用clipRect - 解释

48
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);
    } 
}
我的问题是,上面的代码不应该绘制一个矩形并裁剪左上部分吗?矩形没有被裁剪。 请解释一下clipRect的作用。它实际上是在剪切什么?它是否按照矩形的坐标裁剪?如果是这样,为什么上面的代码不起作用?

3
请查看此链接:http://youtu.be/vkTn3Ule4Ps?list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu - Francisco Corrales Morales
4个回答

85

Canvas.clipRect(left, top, right, bottom)方法会缩小屏幕上未来绘制操作可以写入的区域。它将裁剪边界设置为当前裁剪矩形与指定矩形的空间交集。该方法有很多变体,接受不同形式的区域并允许对裁剪矩形进行不同操作。如果您想显式设置裁剪区域,请尝试使用:

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

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

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

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

在您现有的clipRect语句之后,添加以下代码。它应该在之前的基础上绘制一个50x50的黄色正方形。

另一个注意点:(通过长时间与明显大部分没有文档记录的View/ViewGroup/drawing代码的挣扎)我发现canvas.translate(x,y)也调整了clipRect。clipRect和绘图矩阵的交互非常令人困惑。需要指出的是:

canvas.getMatrix()

canvas.getClipBounds()

在对画布进行修改并绘制物体之前和之后。


2
canvas.translate(x,y)对clipRect的影响的注释非常有用。让我省了很多的挫败感。谢谢! - Dev N
2
现在使用 Region.Op 的方法显然已经被弃用了。 - Suragch
如何从裁剪后的画布中获取原始画布? - Rohan Bhatia
1
@androiddeveloper,clipRect方法的文档推荐了一些替代方案。你为什么说带有Region.OpclipRect(和clipPath)不是技术上的方法? - Suragch
@Suragch 好的,我会看看我能做些什么。忘掉关于方法的那部分吧。我以为你指的是其他东西(Region.Op值是方法),但你指的是使用Region.Opcanvas的方法。 - android developer
显示剩余4条评论

5
要裁剪左上角的部分,请执行以下操作:
canvas.clipRect(0,0,50,50, Region.Op.DIFFERENCE);
// secondly...
canvas.drawRect(0,0,100,100, paint); 

4

ICS及以上版本如果启用了硬件加速,XOR、Difference和ReverseDifference剪裁模式将被忽略。

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

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

参考Android: Howto use clipRect in API15


3

如果不使用cliprect,则绘制的图形如下:

enter image description here

现在,如果我们使用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);
    }

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

enter image description here

如果我们使用相交(intersect)选项,则是相反的效果,看起来像这样:enter image description here

我希望看到有人能够使它具有圆角。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接