模仿刮刮乐。用手指在上面划动可以显示下面的内容。
类似于涂鸦组件,只不过绘制path时将path设置成透明的,这样就显示出底层的图片了。为了使path成透明的了,需要为Paint设置xformode。
private Paint mPaint; public SampleView(Context context) { super(context); init(); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(0x00FF0000);//代码二(1) mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(20); mPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));//代码二(2) mBgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img10); } private Bitmap mBitmap, mBgBitmap;//后一个指的是滑动后要显示的图像 private Canvas mCanvas; private Path mPath; private Paint mBitmapPaint; @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); mCanvas.drawColor(Color.GRAY);//首先绘制一层灰色,这是开始时显示的颜色 } private float mX, mY; private static final float TOUCH_TOLERANCE = 4; @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBgBitmap, 0, 0, mBitmapPaint); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mCanvas.drawPath(mPath, mPaint);//代码一 mX = x; mY = y; } } private void touch_up() { mPath.lineTo(mX, mY); // commit the path to our offscreen mCanvas.drawPath(mPath, mPaint); // kill this so we don't double draw mPath.reset(); }
与涂鸦组件相比,onDraw是变化最大的。并没有调用canvas.drawPath(),因为在代码一处直接将path画到了mCanvas中,这样在onDraw()中第二行绘制mBitmap时就会将path绘制上。
在代码二处,为mPaint设置了颜色及xformode。在代码一处绘制的path属于src,当xformode为src_in时,那么path路径上显示的就是path的图样。又由于mPaint是透明的,所以手指划过之后就显示出底部图形。
代码二处也并不止这一种设置法,也可以如下:
mPaint.setColor(0x00FF0000); mPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
还可以:
mPaint.setColor(0xffFF0000);//完全不透明 mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT));
这样也行
mPaint.setColor(0x00FF0000); mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));