很多传统做法如下,
1.继承ImageView
2.ImageView 的canvas先不用。
3.创建一个临时Canvas,传入一个bitmap作保存,将ImageView的getDrawable()得到的drawable画到上面
mbitmap = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
Canvas bitmapCanvas = new Canvas(mbitmap);
drawable.draw(bitmapCanvas);
4.再创建一个临时CircleCanvas,也传入一个circlebitmap做保存, 画一个圆形。得到一个圆形circlebitmap
circle = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
Canvas circlecanvas = new Canvas(circle);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
circlecanvas.drawOval(new RectF(0.0f, 0.0f, width, height), paint);
5.在第一个Canvas 中 用Dst_In模式绘制circlebitmap,得到最终的 bitmap
maskPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
bitmapCanvas.drawBitmap(circle, 0.0f, 0.0f, maskPaint);
6.将此bitmap绘制到ImageView 的canvas上
canvas.drawBitmap(mbitmap, 0, 0, mPaint);
感觉前期跟View自身的canvas 根本没啥事。
比较好的,逻辑比较清晰的做法如下,通过saveLayer,绘制到离屏缓冲,可以理解为临时的一个视图层上,而且也只用到一个临时canvas,逻辑也更加清晰,
@Override
protected void onDraw(Canvas canvas) {
int saved2 = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
canvas.drawBitmap(recTangleBitmap, 0, 0, mPaint);
mPaint.setXfermode(xfermode);
canvas.drawBitmap(getCircleBitmap(), 0, 0, mPaint);
mPaint.setXfermode(null);
canvas.restoreToCount(saved2);
}
private Bitmap getCircleBitmap() {
Bitmap bitmap = Bitmap.createBitmap(viewWith, viewHeight, Config.ARGB_8888);
Canvas mCanvas = new Canvas(bitmap);
mCanvas.drawCircle(0, 0, 70, circlePaint);
return bitmap;
}