刮刮乐效果的实现

刮刮乐效果的实现思路如下:

  1. 先在视图上画真正要显示的图像
  2. 在第一步绘制的图像上面再绘制一个一样大小的纯灰色图像,彻底盖住第一步中绘制的图像
  3. 随着手指在灰色图像上的滑动不断的修改灰色图像的内容。修改的时候,利用混合模式,灰色图像相当于DST,每次手指划过的路径相当于SRC,采用SRC_IN混合模式让DST与SRC交叠的区域仅仅显示SRC的内容。此时如果SRC是透明的,那么就可以透出下面被覆盖住的图像了。
本例用的是一个自定义View。自定义View在构造器中初始化画笔,fgCanvas,背景图案和前景图案;在onDraw方法中进行图像的绘制工作,在onTouchEvent方法中捕获手指在屏幕上的动作。下面是 一些核心的代码片段:
首先是准备图像和画笔的准备
private void initBitmap() {
		//R.drawable.a是我们想显示的真正图像
		Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.a);
		bg = Bitmap.createScaledBitmap(b, screenWidth, screenHeihgt, true);
		//fg与bg一样大
		fg = Bitmap.createBitmap(screenWidth, screenHeihgt, Config.ARGB_8888);
		//利用fgCanvas,可以随时修改fg的内容
		fgCanvas = new Canvas(fg);
		//将fg全部“涂”成灰色
		fgCanvas.drawColor(Color.LTGRAY);
		//设置画笔,到时候就要利用这根画笔来修改fg
		fgPaint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.DITHER_FLAG);
		//要将画笔设置为透明的。这样画笔画出的内容就是透明的,这样才能透出bg的图像
		fgPaint.setAlpha(0);
		//一些常规性设置
		fgPaint.setStrokeCap(Paint.Cap.ROUND);
		fgPaint.setStrokeJoin(Paint.Join.ROUND);
		fgPaint.setStyle(Paint.Style.STROKE);
		fgPaint.setStrokeWidth(60);
		//利用画笔绘制SRC的时候,SRC与fg交叠的部分只会显示出SRC的内容
                //而这部分内容根据画笔的设置,将是透明的
		fgPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		mPath = new Path();
	}

 将图像画到视图上
protected void onDraw(Canvas canvas) {
		//将bg画到视图上
		canvas.drawBitmap(bg, 0, 0, null);
		//将fg画到视图上,fg会盖在bg上面
		canvas.drawBitmap(fg, 0, 0, null);
		//将mPath作为SRC绘制到fg上,mPath和fg相交的部分,只会显示mPath
		//而因为fgPaint的设置,绘制出来的mPath都是透明的
		fgCanvas.drawPath(mPath, fgPaint);
	}

mPath是随着手指在屏幕上的滑动而不断绘制的,因此要写视图的onTouchEvent方法捕获手指的动作,同事要在onTouchEvent方法中不断调用invalidate来让视图重绘
public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			mPath.reset();
			preX = event.getX();
			preY = event.getY();
			mPath.moveTo(preX, preY);
			break;
		case MotionEvent.ACTION_MOVE:
			float x = event.getX();
			float y = event.getY();
			mPath.quadTo(preX, preY, x, y);
			preX = x;
			preY = y;
			break;
		case MotionEvent.ACTION_UP:
			float x1 = event.getX();
			float y1 = event.getY();
			if(Math.abs(x1-preX)>=SLOP||Math.abs(y1-preY)>=SLOP){
				mPath.quadTo(preX, preY, x1, y1);
			}
			break;
		}
		//随着手指的动作,要求调用onDraw方法进行重绘
		invalidate();
		return true;
	}

最终的效果是

                

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值