用自定义view实现刮刮乐
今天闲来无事,想实现一个刮刮乐
开始觉得很简单,做的时候发现好乱,做完回头看看发现又是好简单。。。
实现思路:利用view的ondraw方法, 不断重新绘制bitmap(我们刮刮乐的涂层图片),然后在重写onTouchEvent的方法里面对bitmap(刮刮乐涂层图片)进行局部透明度处理。
不多说,直接贴代码,实现效果很简单,如果有不了解的地方可以评论或者870135993私聊我
public class CanvasView extends View { private Paint paint; int width; int height; int y = 0; int x = 0; Bitmap bitmap;//要被改动的图 int marginTop = 300;//图片与屏幕顶部距离 int widthScale = 1;//图宽的缩放比 int heightScale = 3;//图高的缩放比 int size = 10;//长方条的长宽,用于画长方条 int r = 30;//画圆的半径,用于画圆 public CanvasView(Context context) { super(context, null); } public CanvasView(Context context, AttributeSet attrs) { super(context, attrs, 0); paint = new Paint(); height = ((Activity) context).getWindowManager().getDefaultDisplay().getHeight(); width = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth(); bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.gray_back); float scaleWidth = ((float) width / widthScale) / bitmap.getWidth(); float scaleHeight = ((float) height / heightScale) / bitmap.getHeight(); Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(bitmap, 0, marginTop, paint); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: y = (int) event.getY(); x = (int) event.getX(); break; case MotionEvent.ACTION_MOVE: y = (int) event.getY(); x = (int) event.getX(); break; default: break; } // drawRect();//画长条 drawCircle();//画圆 return true; } //画长方条 private void drawRect() { if (x >= size && x < (bitmap.getWidth() - size) && (y >= (marginTop + size)) && y < (bitmap.getHeight() + (marginTop - size))) { bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); //画一长方条 for (int i = -size; i < size; i++) { for (int j = -size; j < size; j++) { bitmap.setPixel(x + i, y - marginTop + j, Color.TRANSPARENT); //替换成透明色 } } invalidate(); } } //画圆 private void drawCircle() { if (x >= 0 && x < bitmap.getWidth() && y >= marginTop && y < bitmap.getHeight() + marginTop) { bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); for (int i = 0; i < 360; i++) { double rad = i * Math.PI / 180; //计算弧度 int y1 = (int) (r * Math.sin(rad) + y) - marginTop; int x1 = (int) (r * Math.cos(rad) + x); int length = y1 - (y - marginTop); for (int j = 0; j < Math.abs(length); j++) { if (length >= 0) { if (x1 >= 0 && x1 < bitmap.getWidth() && (y1 - j) >= 0 && (y1 - j) < bitmap.getHeight()) { bitmap.setPixel(x1, y1 - j, Color.TRANSPARENT); //上半圆替换成透明色 } } else { if (x1 >= 0 && x1 < bitmap.getWidth() && (y1 + j) >= 0 && (y1 + j) < bitmap.getHeight()) { bitmap.setPixel(x1, y1 + j, Color.TRANSPARENT); //下半圆替换成透明色 } } } } for (int i = x - r; i < x + r; i++) { if (i >= 0 && i < bitmap.getWidth()) { bitmap.setPixel(i, y - marginTop, Color.TRANSPARENT); //圆中间那条线变透明 } } } invalidate(); } }每次改好刮刮乐涂层之后,都要调用invalidate()方法,要求view重新执行ondraw()方法即可;