转载请标明出处:http://blog.csdn.net/u011546655/article/details/45173197
好久没有写博客了,今天有正好有时间,接下来为大家带来一款电商中要使用的刮刮卡项目,刮刮卡相信大家小时候都玩过,那个时候,可能大家使用的是小纸片的,现在也可以带大家重温小时候的美好时光,今天将这个刮刮卡的项目分享给大家,希望对大家有学习和工作上的帮助。
一:先上效果图
二:原理分析
1.创建一张你想要的bitmap大小,然后根据bitmap的大小,绘制一张画布在上面,然后重写onDraw()方法
2.在刮开面积的不断扩张中,计算扩张面的面积大小,当面积超过60%的时候,就清楚图层
3.下面的刮刮卡信息,可以利用java中的随机数做,可以其是900的倍数什么的,才中奖,这个随意发挥
三:源码示例
自定义控件代码:
package com.zengtao.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
/**
* 刮刮卡
*
* @author zengtao 2015年4月17日 上午11:13:46
*/
@SuppressLint("DrawAllocation")
public class GuaGuaKa extends View {
// -------1.遮盖层的东西
private int lastX;
private int lastY;
private int height = 300;
private int width = 120;
private int movingX;
private int movingY;
private Bitmap mBitmap;
private Paint mPaint;
private Canvas mCanvas;
private Path mPath;
// --------2.遮盖层下的东西
private String mText;
private Paint mTextPaint;
private int mTextSize;
private Rect mRectBounds; // 获取刮刮奖信息的宽和高
private int[] mPixels;
private volatile boolean isComlemete = false;
private Message msg;
private setOnGuaGuaComplemeteListener mGuaGuaComplemeteListener;
public void setOnGuaGuaComplemeteListener(
setOnGuaGuaComplemeteListener mGuaGuaComplemeteListener) {
this.mGuaGuaComplemeteListener = mGuaGuaComplemeteListener;
}
public GuaGuaKa(Context context) {
super(context);
init(context);
}
public GuaGuaKa(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 1.1获取高度和宽度
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
// 1.2获取宽高在初始化Bitmap
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
// 1.3设置绘制path画笔的属性
setPath();
// 2.1 设置textPaint属性
setTextMessagePaint();
mCanvas.drawColor(Color.parseColor("#C7C7C7"));
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
movingX = (int) event.getX();
movingY = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchDown(event);
break;
case MotionEvent.ACTION_MOVE:
touchMove(event);
break;
case MotionEvent.ACTION_UP:
touchUp(event);
break;
default:
break;
}
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawText(mText, getWidth() / 2 - mRectBounds.width() / 2,
getHeight() / 2 + mRectBounds.height() / 2, mTextPaint);
if (!isComlemete) {
drawPath();
canvas.drawBitmap(mBitmap, 0, 0, null);
}
}
// 画path
private void drawPath() {
mPaint.setXfermode(new PorterDuffXfermode(
android.graphics.PorterDuff.Mode.DST_OUT));
mCanvas.drawPath(mPath, mPaint);
}
// 手势抬起
private void touchUp(MotionEvent event) {
new Thread(mRunnable).start();
}
// 手势放下
private void touchMove(MotionEvent event) {
int dx = Math.abs(movingX - lastX);
int dy = Math.abs(movingY - lastY);
if (dx > 3 || dy > 3) {
mPath.lineTo(movingX, movingY);
}
lastX = movingX;
lastY = movingY;
}
// 手势按下
private void touchDown(MotionEvent event) {
lastX = movingX;
lastY = movingY;
mPath.moveTo(lastX, lastY);
}
/**
* 设置绘制path画笔的属性
*/
private void setPath() {
mPaint.setColor(Color.parseColor("#c0c0c0"));
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(40);
}
/**
* 设置画刮刮卡画笔的属性
*/
private void setTextMessagePaint() {
mTextPaint.setColor(Color.DKGRAY);
mTextPaint.setTextSize(mTextSize);
mTextPaint.setStyle(Style.FILL);
// 获取的当前画笔绘制文本的宽和高
mTextPaint.getTextBounds(mText, 0, mText.length(), mRectBounds);
}
/**
* 初始化
*
* @param context
*/
private void init(Context context) {
// ----1.遮盖层
mPaint = new Paint();
mPath = new Path();
// ----2.遮盖层下的内容
mTextPaint = new Paint();
mRectBounds = new Rect();
mText = "谢谢惠顾";
mTextSize = 40;
}
/**
* 开启线程计算用户擦除了多少区域
*/
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
int w = getWidth();
int h = getHeight();
float wipeArea = 0;
float totalArea = w * h;
Bitmap bitmap = mBitmap;
if (mPixels == null) {
mPixels = new int[w * h];
}
// 获取bitmap上所有的像素信息
bitmap.getPixels(mPixels, 0, w, 0, 0, w, h);
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
int index = i + j * w;
if (mPixels[index] == 0) {
wipeArea++;
}
}
}
if (wipeArea > 0 && totalArea > 0) {
int percent = (int) (wipeArea * 100 / totalArea);
Log.e("System.out", "区域---" + percent);
// 清楚图层区域
if(percent > 60) {
isComlemete = true;
postInvalidate();
}
// 如果用户在调用Toast的时候,不能再子线程中做,这样的情况是属于在子线程中跟新ui,所以用handle在主线程中操作
msg = mHandler.obtainMessage();
msg.what = 0x1;
msg.arg1 = percent;
mHandler.sendMessage(msg);
}
}
};
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (mGuaGuaComplemeteListener != null) {
int percent = msg.arg1;
if (percent < 60) {
mGuaGuaComplemeteListener.notEnough("亲,您在刮点吧,还不够! 55555");
} else {
mGuaGuaComplemeteListener.complemete(mText);
}
}
};
};
public interface setOnGuaGuaComplemeteListener {
void complemete(String result);
void notEnough(String result);
}
}
package com.zengtao.testdemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import com.zengtao.view.GuaGuaKa;
import com.zengtao.view.GuaGuaKa.setOnGuaGuaComplemeteListener;
public class MainActivity extends Activity {
private GuaGuaKa mGuaGuaKa;
private Button reStart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGuaGuaKa = (GuaGuaKa) findViewById(R.id.scratch);
reStart = (Button) findViewById(R.id.reStart);
mGuaGuaKa.setOnGuaGuaComplemeteListener(new setOnGuaGuaComplemeteListener() {
@Override
public void complemete(String result) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT)
.show();
}
@Override
public void notEnough(String result) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT)
.show();
}
});
}
}
四:以上便可以完成刮刮卡的实现,看着还是挺简单的,那么你也来试一试吧,蚊子虽小,却也是肉,来拿吧
Demo下载地址:http://download.csdn.net/detail/u011546655/8617235