下面是一个简化的描述:想象一下,给我一个 View 类,它绘制了一面墙的图片,我想绘制它并切掉一个窗口。假设我扩展了该 View 类并重写了它的 dispatchDraw() 方法来执行以下操作。如果有可以通过窗口看到的背景,请先绘制背景。接下来我想以某种方式屏蔽矩形窗口区域,然后调用 super.dispatchDraw()。最后我想去掉面具,画一个站在窗边的人,这样他们就被画在背景和墙上。我怎样才能做到这一点?
这是一些似乎接近我需要的代码:
@Override
protected void dispatchDraw(Canvas into) {
int w = into.getWidth();
int h = into.getHeight();
int w3 = w / 3;
int h3 = h / 3;
into.drawLine(0, 0, w, h, mPaint);
Region protect = new Region(w / 3, h / 3, 2 * w / 3, 2 * h / 3);
into.clipRegion(protect, Op.INTERSECT);
into.drawColor(Color.MAGENTA); // or super.dispatchDraw() here.
}
这给了我这个:
这与我想要的相反。请注意上面代码中名为“protect”的区域。我希望洋红色填充出现在除该区域之外的任何地方。具体来说,我想看到的是:
以窗户的类比,然后我应该可以取消限制并以正常方式绘制一个人或某物,同时覆盖窗户和墙壁。
编辑:这是 Rajesh CP 答案的简化工作版本。我还在最后添加了一条红色的“前景”条纹,以显示我可以删除限制以及添加它们。谢谢拉杰什!
public class MaskTest extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new ClippView(getApplicationContext()));
}
private class ClippView extends View {
private Paint line_paint = new Paint();
private Paint strip_paint = new Paint();
public ClippView(Context context) {
super(context);
line_paint.setColor(Color.GRAY);
line_paint.setStrokeWidth(20);
strip_paint.setColor(Color.RED);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int w = canvas.getWidth();
int h = canvas.getHeight();
int w3 = w / 3;
int h3 = h / 3;
// This line represents some unknown background that we are drawing over.
canvas.drawLine(0, 0, w, h, line_paint);
// 'protect' represents some area to not paint over until desired.
Region protect = new Region(w3, h3, 2 * w / 3, 2 * h / 3);
canvas.clipRegion(protect, Op.DIFFERENCE);
// Paint magenta over the entire canvas, avoiding the protected region.
canvas.drawColor(Color.MAGENTA);
// Remove the protected region.
Region all = new Region(0, 0, w, h);
canvas.clipRegion(all, Op.UNION);
// Draw a wide foreground strip over the entire canvas.
canvas.drawRect(w / 2 - w / 20, 0, w / 2 + w / 20, h, strip_paint);
}
}
}