刮刮乐效果

功能

        模仿刮刮乐。用手指在上面划动可以显示下面的内容。

原理

        类似于涂鸦组件,只不过绘制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));




你可能感兴趣的:(刮刮乐效果)