为什么你可以花几个小时做某事,放弃,提出问题,然后在 20 分钟后偶然发现答案?生活的乐趣。
Path path = new Path();
path.addCircle(kHorizontalOffset, kScreenVerticalOffset, radius, Path.Direction.CW);
canvas.clipPath(path);
我错过了 clipPath 方法,该方法将采用任何路径并将其用作剪切区域。将我的遮罩圈添加到路径中正是我所需要的。
[编辑]
这很好用,但是有一个问题。如果打开硬件加速,它就不起作用。我可以关闭加速,但随后在复杂的平局的其余部分中我失去了很多性能。
这是我最终解决的方法:
在onSizeChanged()
中,创建位图蒙版。我使用这种颜料在位图的正确位置绘制了一个透明圆圈。的关键是使用PorterDuffXfermode
.
maskPaint = new Paint();
maskPaint.setColor(Color.TRANSPARENT);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
maskPaint.setStyle(Paint.Style.FILL);
然后创建位图
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
createMask(w,h,this.radius);
}
private void createMask(int w,int h, int radius){
if (mask!=null){mask.recycle();}
mask = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas maskCanvas = new Canvas(mask);
maskCanvas.drawCircle(w, h, radius, maskPaint);
}
然后在 onDraw() 中,我只是在整个视图上绘制蒙版:
@Override
protected void onDraw(Canvas canvas){
// draw the image();
setRadius(drawGmpImage(this.gmpImage, canvas));
canvas.drawCircle(kHorizontalOffset, kScreenVerticalOffset, radius , maskPaint);
// overlay the mask bitmap
if (mask != null) {
canvas.drawBitmap(mask, 0f, 0f, bitmapPaint);
}
如果半径发生变化,则重新创建蒙版:
private void setRadius(int radius){
this.radius = radius;
createMask(kHorizontalOffset, kScreenVerticalOffset, radius);
}