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

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

劝君更尽一杯酒,西出阳关无故人。

直接拿来用的Android刮奖控件

相关文章:

你感兴趣的文章:

标签云: