好久没有写博客了,今天有正好有时间,接下来为大家带来一款电商中要使用的刮刮卡项目,刮刮卡相信大家小时候都玩过,那个时候,可能大家使用的是小纸片的,现在也可以带大家重温小时候的美好时光,今天将这个刮刮卡的项目分享给大家,希望对大家有学习和工作上的帮助。
一:先上效果图
二:原理分析
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();
- }
- });
- }
- }
四:以上便可以完成刮刮卡的实现,看着还是挺简单的,那么你也来试一试吧,蚊子虽小,却也是肉,来拿吧