Android 刮刮卡

  好久没有写博客了,今天有正好有时间,接下来为大家带来一款电商中要使用的刮刮卡项目,刮刮卡相信大家小时候都玩过,那个时候,可能大家使用的是小纸片的,现在也可以带大家重温小时候的美好时光,今天将这个刮刮卡的项目分享给大家,希望对大家有学习和工作上的帮助。


一:先上效果图






二:原理分析

1.创建一张你想要的bitmap大小,然后根据bitmap的大小,绘制一张画布在上面,然后重写onDraw()方法

2.在刮开面积的不断扩张中,计算扩张面的面积大小,当面积超过60%的时候,就清楚图层

3.下面的刮刮卡信息,可以利用java中的随机数做,可以其是900的倍数什么的,才中奖,这个随意发挥


三:源码示例


自定义控件代码:

[html]  view plain copy
  1. package com.zengtao.view;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.content.Context;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.Canvas;  
  7. import android.graphics.Color;  
  8. import android.graphics.Paint;  
  9. import android.graphics.Paint.Style;  
  10. import android.graphics.Path;  
  11. import android.graphics.PorterDuffXfermode;  
  12. import android.graphics.Rect;  
  13. import android.os.Handler;  
  14. import android.os.Message;  
  15. import android.util.AttributeSet;  
  16. import android.util.Log;  
  17. import android.view.MotionEvent;  
  18. import android.view.View;  
  19.   
  20. /**  
  21.  * 刮刮卡  
  22.  *   
  23.  * @author zengtao 2015年4月17日 上午11:13:46  
  24.  */  
  25. @SuppressLint("DrawAllocation")  
  26. public class GuaGuaKa extends View {  
  27.   
  28.     // -------1.遮盖层的东西  
  29.     private int lastX;  
  30.     private int lastY;  
  31.     private int height = 300;  
  32.     private int width = 120;  
  33.     private int movingX;  
  34.     private int movingY;  
  35.     private Bitmap mBitmap;  
  36.     private Paint mPaint;  
  37.     private Canvas mCanvas;  
  38.     private Path mPath;  
  39.   
  40.     // --------2.遮盖层下的东西  
  41.     private String mText;  
  42.     private Paint mTextPaint;  
  43.     private int mTextSize;  
  44.     private Rect mRectBounds; // 获取刮刮奖信息的宽和高  
  45.   
  46.     private int[] mPixels;  
  47.     private volatile boolean isComlemete = false;  
  48.     private Message msg;  
  49.   
  50.     private setOnGuaGuaComplemeteListener mGuaGuaComplemeteListener;  
  51.   
  52.     public void setOnGuaGuaComplemeteListener(  
  53.             setOnGuaGuaComplemeteListener mGuaGuaComplemeteListener) {  
  54.         this.mGuaGuaComplemeteListener = mGuaGuaComplemeteListener;  
  55.     }  
  56.   
  57.     public GuaGuaKa(Context context) {  
  58.         super(context);  
  59.         init(context);  
  60.     }  
  61.   
  62.     public GuaGuaKa(Context context, AttributeSet attrs) {  
  63.         super(context, attrs);  
  64.         init(context);  
  65.     }  
  66.   
  67.     @SuppressLint("DrawAllocation")  
  68.     @Override  
  69.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  70.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  71.         // 1.1获取高度和宽度  
  72.         width = MeasureSpec.getSize(widthMeasureSpec);  
  73.         height = MeasureSpec.getSize(heightMeasureSpec);  
  74.         // 1.2获取宽高在初始化Bitmap  
  75.         mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);  
  76.         mCanvas = new Canvas(mBitmap);  
  77.         // 1.3设置绘制path画笔的属性  
  78.         setPath();  
  79.   
  80.         // 2.1 设置textPaint属性  
  81.         setTextMessagePaint();  
  82.         mCanvas.drawColor(Color.parseColor("#C7C7C7"));  
  83.     }  
  84.   
  85.     @SuppressLint("ClickableViewAccessibility")  
  86.     @Override  
  87.     public boolean onTouchEvent(MotionEvent event) {  
  88.         movingX = (int) event.getX();  
  89.         movingY = (int) event.getY();  
  90.         switch (event.getAction()) {  
  91.         case MotionEvent.ACTION_DOWN:  
  92.             touchDown(event);  
  93.             break;  
  94.         case MotionEvent.ACTION_MOVE:  
  95.             touchMove(event);  
  96.             break;  
  97.         case MotionEvent.ACTION_UP:  
  98.             touchUp(event);  
  99.             break;  
  100.         default:  
  101.             break;  
  102.         }  
  103.         invalidate();  
  104.         return true;  
  105.     }  
  106.   
  107.     @Override  
  108.     protected void onDraw(Canvas canvas) {  
  109.         canvas.drawText(mText, getWidth() / 2 - mRectBounds.width() / 2,  
  110.                 getHeight() / 2 + mRectBounds.height() / 2, mTextPaint);  
  111.         if (!isComlemete) {  
  112.             drawPath();  
  113.             canvas.drawBitmap(mBitmap, 0, 0, null);  
  114.         }  
  115.     }  
  116.   
  117.     // 画path  
  118.     private void drawPath() {  
  119.         mPaint.setXfermode(new PorterDuffXfermode(  
  120.                 android.graphics.PorterDuff.Mode.DST_OUT));  
  121.         mCanvas.drawPath(mPath, mPaint);  
  122.     }  
  123.   
  124.     // 手势抬起  
  125.     private void touchUp(MotionEvent event) {  
  126.         new Thread(mRunnable).start();  
  127.     }  
  128.   
  129.     // 手势放下  
  130.     private void touchMove(MotionEvent event) {  
  131.         int dx = Math.abs(movingX - lastX);  
  132.         int dy = Math.abs(movingY - lastY);  
  133.         if (dx > 3 || dy > 3) {  
  134.             mPath.lineTo(movingX, movingY);  
  135.         }  
  136.         lastX = movingX;  
  137.         lastY = movingY;  
  138.     }  
  139.   
  140.     // 手势按下  
  141.     private void touchDown(MotionEvent event) {  
  142.         lastX = movingX;  
  143.         lastY = movingY;  
  144.         mPath.moveTo(lastX, lastY);  
  145.     }  
  146.   
  147.     /**  
  148.      * 设置绘制path画笔的属性  
  149.      */  
  150.     private void setPath() {  
  151.         mPaint.setColor(Color.parseColor("#c0c0c0"));  
  152.         mPaint.setAntiAlias(true);  
  153.         mPaint.setDither(true);  
  154.         mPaint.setStrokeJoin(Paint.Join.ROUND);  
  155.         mPaint.setStrokeCap(Paint.Cap.ROUND);  
  156.         mPaint.setStyle(Paint.Style.STROKE);  
  157.         mPaint.setStrokeWidth(40);  
  158.     }  
  159.   
  160.     /**  
  161.      * 设置画刮刮卡画笔的属性  
  162.      */  
  163.     private void setTextMessagePaint() {  
  164.         mTextPaint.setColor(Color.DKGRAY);  
  165.         mTextPaint.setTextSize(mTextSize);  
  166.         mTextPaint.setStyle(Style.FILL);  
  167.         // 获取的当前画笔绘制文本的宽和高  
  168.         mTextPaint.getTextBounds(mText, 0, mText.length(), mRectBounds);  
  169.     }  
  170.   
  171.     /**  
  172.      * 初始化  
  173.      *   
  174.      * @param context  
  175.      */  
  176.     private void init(Context context) {  
  177.         // ----1.遮盖层  
  178.         mPaint = new Paint();  
  179.         mPath = new Path();  
  180.         // ----2.遮盖层下的内容  
  181.         mTextPaint = new Paint();  
  182.         mRectBounds = new Rect();  
  183.         mText = "谢谢惠顾";  
  184.         mTextSize = 40;  
  185.     }  
  186.   
  187.     /**  
  188.      * 开启线程计算用户擦除了多少区域  
  189.      */  
  190.     private Runnable mRunnable = new Runnable() {  
  191.   
  192.         @Override  
  193.         public void run() {  
  194.             int w = getWidth();  
  195.             int h = getHeight();  
  196.   
  197.             float wipeArea = 0;  
  198.             float totalArea = w * h;  
  199.             Bitmap bitmap = mBitmap;  
  200.   
  201.             if (mPixels == null) {  
  202.                 mPixels = new int[w * h];  
  203.             }  
  204.             // 获取bitmap上所有的像素信息  
  205.             bitmap.getPixels(mPixels, 0, w, 0, 0, w, h);  
  206.   
  207.             for (int i = 0; i < w; i++) {  
  208.                 for (int j = 0; j < h; j++) {  
  209.                     int index = i + j * w;  
  210.                     if (mPixels[index] == 0) {  
  211.                         wipeArea++;  
  212.                     }  
  213.                 }  
  214.             }  
  215.   
  216.             if (wipeArea > 0 && totalArea > 0) {  
  217.                 int percent = (int) (wipeArea * 100 / totalArea);  
  218.                 Log.e("System.out", "区域---" + percent);  
  219.                 // 清楚图层区域  
  220.                 if(percent > 60) {  
  221.                     isComlemete = true;  
  222.                     postInvalidate();  
  223.                 }  
  224.                 // 如果用户在调用Toast的时候,不能再子线程中做,这样的情况是属于在子线程中跟新ui,所以用handle在主线程中操作  
  225.                 msg = mHandler.obtainMessage();  
  226.                 msg.what = 0x1;  
  227.                 msg.arg1 = percent;  
  228.                 mHandler.sendMessage(msg);  
  229.             }  
  230.         }  
  231.     };  
  232.   
  233.     @SuppressLint("HandlerLeak")  
  234.     private Handler mHandler = new Handler() {  
  235.         public void handleMessage(Message msg) {  
  236.             if (mGuaGuaComplemeteListener != null) {  
  237.                 int percent = msg.arg1;  
  238.                 if (percent < 60) {  
  239.                     mGuaGuaComplemeteListener.notEnough("亲,您在刮点吧,还不够! 55555");  
  240.                 } else {  
  241.                     mGuaGuaComplemeteListener.complemete(mText);  
  242.                 }  
  243.             }  
  244.         };  
  245.     };  
  246.   
  247.     public interface setOnGuaGuaComplemeteListener {  
  248.         void complemete(String result);  
  249.   
  250.         void notEnough(String result);  
  251.     }  
  252. }  


二:MainActivity中的实现

[java]  view plain copy
  1. package com.zengtao.testdemo;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.Button;  
  6. import android.widget.Toast;  
  7.   
  8. import com.zengtao.view.GuaGuaKa;  
  9. import com.zengtao.view.GuaGuaKa.setOnGuaGuaComplemeteListener;  
  10.   
  11. public class MainActivity extends Activity {  
  12.     private GuaGuaKa mGuaGuaKa;  
  13.     private Button reStart;  
  14.   
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_main);  
  19.   
  20.         mGuaGuaKa = (GuaGuaKa) findViewById(R.id.scratch);  
  21.         reStart = (Button) findViewById(R.id.reStart);  
  22.         mGuaGuaKa.setOnGuaGuaComplemeteListener(new setOnGuaGuaComplemeteListener() {  
  23.   
  24.             @Override  
  25.             public void complemete(String result) {  
  26.                 Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT)  
  27.                         .show();  
  28.             }  
  29.   
  30.             @Override  
  31.             public void notEnough(String result) {  
  32.                 Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT)  
  33.                 .show();  
  34.             }  
  35.         });  
  36.     }  
  37. }  


四:以上便可以完成刮刮卡的实现,看着还是挺简单的,那么你也来试一试吧,蚊子虽小,却也是肉,来拿吧


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值