直接拿来用的Android刮奖控件

直接上效果图

功能特色:
 1、可以设置刮开后显示文字或图片
 2、可以统计已刮开区域所占百分比

Demo下载地址:RubberDemo.rar

下面是源码:

@SuppressLint("HandlerLeak")
public class RubberView extends TextView {

 private static final int W = 480;
 private static final int H = 800;
 private static final int MV = 1;
 private static final int SW = 50;
 private static final int MC = 0xFFD6D6D6;

 private int mWidth;
 private int mHeight;
 private int mMaskColor;
 private int mStrokeWidth;
 private float mX;
 private float mY;
 private boolean mRun;
 private boolean caculate;
 private Path mPath;
 private Paint mPaint;
 private Paint mBitmapPaint;
 private Canvas mCanvas;
 private Bitmap mBitmap;
 private int[] mPixels;
 private Thread mThread;
 private onWipeListener mWipeListener;

 public RubberView(Context context) {
 super(context);
 init(context);
 }

 public RubberView(Context context, AttributeSet attrs) {
 super(context, attrs);
 init(context);
 }

 private final void init(Context context) {
 mMaskColor = MC;
 mStrokeWidth = SW;

 mPath = new Path();
 mBitmapPaint = new Paint();

 mPaint = new Paint();
 mPaint.setAntiAlias(true);// 抗锯齿
 mPaint.setDither(true);// 递色
 mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
 mPaint.setStyle(Paint.Style.STROKE);
 mPaint.setStrokeJoin(Paint.Join.ROUND); // 前圆角
 mPaint.setStrokeCap(Paint.Cap.ROUND); // 后圆角
 mPaint.setStrokeWidth(mStrokeWidth); // 笔宽

 mBitmap = Bitmap.createBitmap(W, H, Config.ARGB_8888);
 mCanvas = new Canvas(mBitmap);
 mCanvas.drawColor(mMaskColor);

 mRun = true;
 mThread = new Thread(mRunnable);
 mThread.start();

 setGravity(Gravity.CENTER);
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 mCanvas.drawPath(mPath, mPaint);
 canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 int w = MeasureSpec.getSize(widthMeasureSpec);
 int h = MeasureSpec.getSize(heightMeasureSpec);
 if (w > 0 && h > 0) {
  mWidth = w;
  mHeight = h;
 }
 }

 public void reset() {
 mPath.reset();
 mCanvas.drawPaint(mPaint);
 mCanvas.drawColor(mMaskColor);
 invalidate();
 }

 public void setOnWipeListener(onWipeListener listerer) {
 this.mWipeListener = listerer;
 }

 public void setStrokeWidth(int width) {
 this.mStrokeWidth = width;
 mPaint.setStrokeWidth(width);
 }

 public void setMaskColor(int color) {
 this.mMaskColor = color;
 reset();
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
 boolean invalidate = false;
 boolean consume = false;
 int action = event.getAction();
 switch (action) {
 case MotionEvent.ACTION_DOWN:
  consume = true;
  touchDown(event);
  break;
 case MotionEvent.ACTION_MOVE:
  consume = true;
  invalidate = touchMove(event);
  break;
 case MotionEvent.ACTION_UP:
  consume = true;
  touchUp(event);
  break;
 }

 if (invalidate) {
  invalidate();
 }

 if (consume) {
  return true;
 }

 return super.onTouchEvent(event);
 }

 // 手指点下屏幕时调用
 private void touchDown(MotionEvent event) {
 caculate = false;
 // 重置绘制路线,即隐藏之前绘制的轨迹
 mPath.reset();
 float x = event.getX();
 float y = event.getY();

 mX = x;
 mY = y;
 // mPath绘制的绘制起点
 mPath.moveTo(x, y);
 }

 // 手指在屏幕上滑动时调用
 private boolean touchMove(MotionEvent event) {
 caculate = false;
 final float x = event.getX();
 final float y = event.getY();

 final float previousX = mX;
 final float previousY = mY;

 // 设置贝塞尔曲线的操作点为起点和终点的一半
 float cX = (x + previousX) / 2;
 float cY = (y + previousY) / 2;

 final float dx = Math.abs(x - previousX);
 final float dy = Math.abs(y - previousY);

 boolean move = false;

 if (dx >= MV || dy >= MV) {
  // 二次贝塞尔,实现平滑曲线;cX, cY为操作点 x,y为终点
  mPath.quadTo(cX, cY, x, y);

  // 第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值
  mX = x;
  mY = y;

  move = true;
 }
 return move;
 }

 private void touchUp(MotionEvent event) {
 caculate = true;
 mRun = true;
 }

 private Runnable mRunnable = new Runnable() {

 @Override
 public void run() {

  while (mRun) {

  SystemClock.sleep(100);

  // 收到计算命令,立即开始计算
  if (caculate) {

   caculate = false;

   int w = mWidth;
   int h = mHeight;

   float wipeArea = 0;
   float totalArea = w * h;

   // 计算耗时100毫秒左右
   Bitmap bitmap = mBitmap;

   if (mPixels == null) {
   mPixels = new int[w * h];
   }

   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);
   Message msg = mHandler.obtainMessage();
   msg.what = 0x1;
   msg.arg1 = percent;
   mHandler.sendMessage(msg);
   }

  }

  }

 }
 };

 private Handler mHandler = new Handler() {
 public void handleMessage(Message msg) {

  if (mWipeListener != null) {
  int percent = msg.arg1;
  mWipeListener.onWipe(percent);
  }

 };
 };

 public interface onWipeListener {
 public void onWipe(int percent);
 }

 @Override
 protected void onDetachedFromWindow() {
 super.onDetachedFromWindow();
 mRun = false;
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • canvas实现刮刮卡效果

    目前在html5和css3的热潮下,html页面的效果也是层出不穷,下面我们来介绍使用canvas来模仿刮奖刮开效果. 原理 在需要刮出的图片或者文字上方盖上一层灰色或者其他背景的canvas画布,当手指或者鼠标点击画布并移动时,将画布上移动过的轨迹变成透明即可. 分析 demo中在class为content的div上盖上一层灰色的画布,然后通过获取鼠标和手指的坐标计算出在画布位置上的坐标,通过在坐标原点位置画一个半径10px的透明圆形来透过画布,显示出画布下的内容.本demo是用时需要改变的内

  • 分享Android仿刮奖效果控件

    本文实例为大家分享了Android刮刮卡效果控件,供大家参考,具体内容如下 刮刮卡类: package com.reyo.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Paint; import android.gr

  • 轻松实现功能强大的Android刮奖效果控件(ScratchView)

    前言 我身边有一部分开发的小伙伴,存在着这样一种习惯.某一天,突然看到某一款 App 上有个很漂亮的自定义控件(动画)效果,就会绞尽脑子想办法去自己实现一发.当然,我自己也是属于这类型的骚年,看到某种效果就会手痒难耐琢磨着实现套路.个人觉得这是一种需求驱动进步的方法,当你绞尽脑子去实现自己想要的效果时,你就会发现你对 Android 自定义控件(动画)的知识体系认识越深,久而久之,自己也能轻松的造出各种控件(动画)效果.要是哪天,产品童鞋拿着个原型(或者对着某款 App )跟你讲:"XXXX,你

  • 直接拿来用的Android刮奖控件

    直接上效果图 功能特色:  1.可以设置刮开后显示文字或图片  2.可以统计已刮开区域所占百分比 Demo下载地址:RubberDemo.rar 下面是源码: @SuppressLint("HandlerLeak") public class RubberView extends TextView { private static final int W = 480; private static final int H = 800; private static final int

  • Android中Spinner控件之键值对用法实例分析

    本文实例讲述了Android中Spinner控件之键值对用法.分享给大家供大家参考.具体如下: 一.字典表,用来存放键值对信息 package com.ljq.activity; import java.io.Serializable; @SuppressWarnings("serial") public class Dict implements Serializable { private Integer id; private String text; public Dict()

  • Android编程布局控件之AbsoluteLayout用法实例分析

    本文实例讲述了Android编程布局控件之AbsoluteLayout用法.分享给大家供大家参考,具体如下: AbsoluteLayout是绝对布局管理器,指的是指定组件的左上角绝对坐标来指定组件的布局 <?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"

  • 分享Android中ExpandableListView控件使用教程

    本文采用一个Demo来展示Android中ExpandableListView控件的使用,如如何在组/子ListView中绑定数据源.直接上代码如下: 程序结构图: layout目录下的 main.xml 文件源码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android

  • Android 代码写控件代替XML简单实例

    Android 代码写控件代替XML简单实例 简单的一个Button控件的练习. 实现代码: Button btn = new Button(HandlerToActivity.this); LinearLayout.LayoutParams params=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.gravity = Gravity.CENTER_HORIZONTAL; param

  • Android编程之控件ListView使用方法

    本文实例讲述了Android编程之控件ListView使用方法.分享给大家供大家参考.具体分析如下: 控件ListView是一个重要的控件,可以被用作用户列表等显示,下面进行它的操作测试. 下面代码实现了生成了一个ListView显示,并对每个条目的单击事件作出响应. 源代码: package com.list; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import an

  • Android实现EditText控件禁止输入内容的方法(附测试demo)

    本文实例讲述了Android实现EditText控件禁止输入内容的方法.分享给大家供大家参考,具体如下: 问题: android如何实现EditText控件禁止往里面输入内容? 修改版解决方法: EditText editText = (EditText) findViewById(R.id.editText1); editText.setKeyListener(null); 看到这个问题大家可能有点奇怪了,EditText的功能不就是往上面写入内容吗? 再者,如果真要禁止输入文本,在布局文件中

  • 如何让安卓(Android)子控件超出父控件的范围显示

    先来看一张预览图: 废话不多说,直接上代码: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false"> <Imag

  • Android自定义组合控件之自定义下拉刷新和左滑删除实例代码

    绪论 最近项目里面用到了下拉刷新和左滑删除,网上找了找并没有可以用的,有比较好的左滑删除,但是并没有和下拉刷新上拉加载结合到一起,要不就是一些比较水的结合,并不能在项目里面使用,小编一着急自己组合了一个,做完了和QQ的对比了一下,并没有太大区别,今天分享给大家,其实并不难,但是不知道为什么网上没有比较好的Demo,当你的项目真的很急的时候,又没有比较好的Demo,那么"那条友谊的小船儿真是说翻就翻啊",好了,下面先来具体看一下实现后的效果吧: 代码已经上传到Github上了,小伙伴们记

  • Android ListView 子控件onClick正确获取position的方法

    在实际开发中,我们有时候不仅需要响应ListView的onItemClick,还需要响应其子控件的点击事件,这个时候我们就会 发现,由于复用等原因,如果直接在子控件的onClick事件中调用getView()中的position,会出现数据或显示错位的问 题,原因就是position的值出现了重复或不准确,解决这个问题的方法是,在adapter每次加载数据的时候,为需要点击 的控件设置一个tag值,这个tag值就设置为当前这个控件对应的position,然后在点击事件中gettag(),获取这个

随机推荐