在做电商类产品时,经常会有一些活动需求,如抽奖,抽奖的一种方式就是刮刮乐,这次的内容是利用重写View的方式实现刮刮乐的效果。

思路:利用Bitmap做刮奖区的蒙版,利用paint将手指触摸过的区域置为透明,即可显示最先draw过的文字或者图片。以下为该View的具体实现:

package com.example.zhangyulong.guajiangtest;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;/**
 * Created by zhangyulong on 16/3/31.
 */
public class RubblerView extends View {private float TOUCH_TOLERANCE; // 填充距离,使线条更自然,柔和,值越小,越柔和。

    // private final int bgColor;
    // 位图
    private Bitmap mBitmap;private Bitmap mCoverBitmap; //覆盖图  刮奖钱的页面

    // 画布
    private Canvas mCanvas;// 画笔
    private Paint mPaint;private Path mPath;private float mX, mY;private Paint mTextPaint;private final int TEXT_SIZE = 60;private String mText;private boolean isDraw = false;private int WIDTH;private int HEIGHT;private int openSize;private Context mContext;private boolean mHasOpen = false;public RubblerView(Context context) {super(context);init(context);}public RubblerView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context);}public RubblerView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}private void init(Context context){mContext = context;//由于我们无法在代码里直接对资源文件作修改,故需要得到资源文件的副本
        mCoverBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.guaguale).copy(Bitmap.Config.ARGB_8888, true);mBitmap = Bitmap.createBitmap(mCoverBitmap.getWidth(),mCoverBitmap.getHeight(), Bitmap.Config.ARGB_8888);mCanvas = new Canvas(mBitmap);WIDTH = mBitmap.getWidth();HEIGHT = mBitmap.getHeight();//mCanvas.drawColor(getContext().getResources().getColor(bgColorResource));
        mCanvas.drawBitmap(mCoverBitmap, 0, 0, new Paint());}@Override
    protected void onDraw(Canvas canvas) {super.onDraw(canvas);if (isDraw) {canvas.drawText(mText, (mCoverBitmap.getWidth() - TEXT_SIZE * mText.length()) / 2,(mCoverBitmap.getHeight() + TEXT_SIZE) / 2 , mTextPaint); //绘制中奖文字
            mCanvas.drawPath(mPath, mPaint);canvas.drawBitmap(mBitmap, 0, 0, null); //绘制刮奖图层
        }}//解决自定义view wrap_content属性失效的问题
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int desiredWidth = WIDTH;int desiredHeight = HEIGHT;int widthMode = MeasureSpec.getMode(widthMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);int width;int height;//Measure Width
        if (widthMode == MeasureSpec.EXACTLY) {//Must be this size
            width = widthSize;} else if (widthMode == MeasureSpec.AT_MOST) {//Can't be bigger than...
            width = Math.min(desiredWidth, widthSize);} else {//Be whatever you want
            width = desiredWidth;}//Measure Height
        if (heightMode == MeasureSpec.EXACTLY) {//Must be this size
            height = heightSize;} else if (heightMode == MeasureSpec.AT_MOST) {//Can't be bigger than...
            height = Math.min(desiredHeight, heightSize);} else {//Be whatever you want
            height = desiredHeight;}//MUST CALL THIS
        setMeasuredDimension(width, height);}/**
     * 开启檫除功能
     *
     * @param paintStrokeWidth 触点(橡皮)宽度
     * @param touchTolerance   填充距离,值越小,越柔和。
     */
    public void beginRubbler(final int paintStrokeWidth,float touchTolerance, String text) {mText = text;TOUCH_TOLERANCE = touchTolerance;// 设置画笔
        mPaint = new Paint();// mPaint.setAlpha(0);
        // 画笔划过的痕迹就变成透明色了
        mPaint.setColor(Color.BLACK); // 此处不能为透明色
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));mPaint.setAntiAlias(true);mPaint.setDither(true);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeJoin(Paint.Join.ROUND); // 前圆角
        mPaint.setStrokeCap(Paint.Cap.ROUND); // 后圆角
        mPaint.setStrokeWidth(paintStrokeWidth); // 笔宽
        mTextPaint = new Paint();mTextPaint.setColor(Color.BLACK);mTextPaint.setStyle(Paint.Style.STROKE);mTextPaint.setTextSize(TEXT_SIZE);// 痕迹
        mPath = new Path();isDraw = true;Thread thread = new Thread(mRunnable);thread.start();}@Override
    public boolean onTouchEvent(MotionEvent event) {if (!isDraw) {return true;}switch (event.getAction()) {case MotionEvent.ACTION_DOWN: // 触点按下
                touchDown(event.getX(), event.getY());invalidate();break;case MotionEvent.ACTION_MOVE: // 触点移动
                touchMove(event.getX(), event.getY());invalidate();break;case MotionEvent.ACTION_UP: // 触点弹起
                touchUp(event.getX(), event.getY());invalidate();break;default:break;}return true;}private void touchDown(float x, float y) {mPath.reset();mPath.moveTo(x, y);mX = x;mY = y;}private void touchMove(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);mX = x;mY = y;}}private void touchUp(float x, float y) {mPath.lineTo(x, y);mCanvas.drawPath(mPath, mPaint);mPath.reset();}private Runnable mRunnable = new Runnable() {@Override
        public void run() {while (!mHasOpen) {SystemClock.sleep(100);float wipeArea = 0;float totalArea = WIDTH * HEIGHT;for (int i = 0; i < WIDTH; i++) {for (int j = 0; j < HEIGHT; j++) {int pixel = mBitmap.getPixel(i, j);if (pixel == 0) {openSize++;}}}//当刮开区域的像素占整个可刮区域的50%时,展示结果
                if (openSize * 100 / totalArea > 50) {mHandler.sendEmptyMessage(0);}openSize = 0; //刮开区域归零
            }}};private Handler mHandler = new Handler() {public void handleMessage(Message msg) {Toast.makeText(mContext, "已经刮开了", Toast.LENGTH_SHORT).show();mHasOpen = true;}};
}

使用时的代码:

package com.example.zhangyulong.guajiangtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;public class MainActivity extends AppCompatActivity {//刮奖控件
    private RubblerView mRubblerView;@Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mRubblerView = (RubblerView) findViewById(R.id.rubbler);mRubblerView.beginRubbler(40,1f , "一等奖");}
}

android 实现刮刮乐刮奖效果相关推荐

  1. Android刮奖效果

    背景知识 使用Xfermode中的PorterDuffXfermode实现我们的刮奖效果 PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter ...

  2. android实现一个橡皮檫效果的自定义View,实现刮奖效果

    最近学习自定义View然后做了这么个东西,感觉挺有趣. 简单的就不写了就是一个Activity然后在其中使用,就像TextView一样,只需要设置宽高就行了wrap_content和match_par ...

  3. HTML5实现刮奖效果

    原文:HTML5实现刮奖效果 要实现刮奖效果,最重要的是要找到一种方法:当刮开上层的涂层是就能看到下层的结果.而HTML5的canvas API中有一个属性globalCompositeOperati ...

  4. 入门canvas - 通过刮奖效果来学习

    一 .前言 一直在做PC端的前端开发,从互联网到行业软件.最近发现移动端已经成为前端必备技能了,真是不能停止学习.HTML5新增的一些东西,canvas是用的比较多也比较复杂的一个,简单的入门了一下, ...

  5. 简单入门canvas - 通过刮奖效果来学习

    一 .前言 一直在做PC端的前端开发,从互联网到行业软件.最近发现移动端已经成为前端必备技能了,真是不能停止学习.HTML5新增的一些东西,canvas是用的比较多也比较复杂的一个,简单的入门了一下, ...

  6. canvas刮奖效果

    上次写刮奖效果都一年前了,那时候还是百度找的源码给改的,自己其实也是迷迷糊糊的,这次因为让妹子写,然后想着自己也重新整理下. <!DOCTYPE html> <html> &l ...

  7. 刮刮奖效果的简单实现

    刮刮奖效果的简单实现 无意中看到个刮刮奖的效果,觉得很有意思.就想自己也做一个,怎样用html5及javascript实现呢,回忆以前 做报表的时候,用过html5 canvas元素.心里就有思路了. ...

  8. html5刮奖效果,HTML5+Canvas实战之刮奖效果

    项目描述 HTML5+Canvas实战之刮奖效果,实现网页上刮奖,可以用作验证码: 可以在移动设备上和PC端网页(浏览器要支持canvas)上运行 ##使用说明 var lottery = new L ...

  9. html5刮奖效果,HTML5 Canvas实战之刮奖效果

    近年来由于移动设备对HTML5的较好支持,经常有活动用刮奖的效果,最近也在看H5方面的内容,就自己实现了一个,现分享出来跟大家交流. 1.效果 2.原理 原理很简单,就是在刮奖区添加两个canvas, ...

  10. html刮奖特效,用CANVAS模拟一个简单的刮奖效果

    用CANVAS模拟一个简单的刮奖效果.html> * { padding: 0; margin: 0; } .box { position: relative; height: 400px; w ...

最新文章

  1. 如何快速搭建智能人脸识别系统
  2. 【一天一个shell命令】文本操作系列-touch
  3. 国王放米粒的C语言程序,云南大学软件学院C语言实验米粒问题.doc
  4. t-sne原理解释_T-SNE解释-数学与直觉
  5. python标准库os的方法listdir_使用python标准库快速修改文件名字
  6. 高斯伪谱法 matlab,Gauss 高斯伪谱法求解的 ,希望对大家有用的!代码比较复杂,但是可以运行。 matlab 263万源代码下载- www.pudn.com...
  7. python之list与set的区别
  8. sql server安装-没有权限访问文件
  9. php 音频上传之ogg格式,如何快速将MP3格式转化成ogg格式
  10. html如何将图片做成背景图片,css如何设置网页背景图片?
  11. python中flag=1什么意思_001_flag包详解
  12. Mac删除已卸载软件残留启动台的图标
  13. 那些老牌互联网公司现在都混得怎样了?
  14. cshop模板smarty foreach详解
  15. win10希望计算机做什么取消,主编设置win10设置和取消定时关机的解决形式
  16. IDEA 配置 JDK 源码
  17. 基于jsp+java+ssm的农产品购物商城系统-计算机毕业设计
  18. 服务器信号满格但网速很慢,4G信号满格网速却很慢?一招搞定!
  19. C/C++编程:Google代码规范
  20. 搜索引擎不收录网站页面的常见原因

热门文章

  1. 半乳糖修饰人血清白蛋白 Gal-HSA,Gal-PEG-HSA,单糖/多糖修饰蛋白等
  2. php抓取微博评论,python爬虫爬取微博评论案例详解
  3. 国开1253c语言程序设计,人教版三年级数学下册单元测试题全套
  4. 京东Java后台开发岗社招面试经验分享,4面的面经
  5. scrum立会报告+燃尽图(第二周第六次)
  6. 基于SVM算法的人脸表情识别
  7. 创新思维对计算机专业的关系,创新思维复习题
  8. CallStranger UPnP 漏洞曝光,影响数十亿台设备
  9. 鸿蒙喜欢吃什么,巴西龟吃什么食物,一般一天喂几次?
  10. 程序员普遍用gmail_使Gmail更好的最佳Chrome扩展程序