欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

直接拿来用的Android刮奖控件

程序员文章站 2024-03-06 10:27:49
直接上效果图   功能特色:  1、可以设置刮开后显示文字或图片  2、可以统计已刮开区域所占百分比  demo下...

直接上效果图

 直接拿来用的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;
 }
}

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