直接拿來用的Android刮獎(jiǎng)控件
直接上效果圖
功能特色:
1、可以設(shè)置刮開后顯示文字或圖片
2、可以統(tǒng)計(jì)已刮開區(qū)域所占百分比
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); } // 手指點(diǎn)下屏幕時(shí)調(diào)用 private void touchDown(MotionEvent event) { caculate = false; // 重置繪制路線,即隱藏之前繪制的軌跡 mPath.reset(); float x = event.getX(); float y = event.getY(); mX = x; mY = y; // mPath繪制的繪制起點(diǎn) mPath.moveTo(x, y); } // 手指在屏幕上滑動(dòng)時(shí)調(diào)用 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; // 設(shè)置貝塞爾曲線的操作點(diǎn)為起點(diǎn)和終點(diǎn)的一半 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) { // 二次貝塞爾,實(shí)現(xiàn)平滑曲線;cX, cY為操作點(diǎn) x,y為終點(diǎn) mPath.quadTo(cX, cY, x, y); // 第二次執(zhí)行時(shí),第一次結(jié)束調(diào)用的坐標(biāo)值將作為第二次調(diào)用的初始坐標(biāo)值 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); // 收到計(jì)算命令,立即開始計(jì)算 if (caculate) { caculate = false; int w = mWidth; int h = mHeight; float wipeArea = 0; float totalArea = w * h; // 計(jì)算耗時(shí)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; } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android之scrollview滑動(dòng)使標(biāo)題欄漸變背景色的實(shí)例代碼
這篇文章主要介紹了Android之scrollview滑動(dòng)使標(biāo)題欄漸變背景色的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05Flutter手勢密碼的實(shí)現(xiàn)示例(附demo)
本文主要介紹了Flutter手勢密碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08android相冊選擇圖片的編碼實(shí)現(xiàn)代碼
本篇文章主要介紹了android相冊選擇圖片的編碼實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08android 中使用TableLayout實(shí)現(xiàn)表單布局效果示例
本篇文章主要介紹了android 中使用TableLayout實(shí)現(xiàn)表單布局效果示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06Android實(shí)現(xiàn)桌面懸浮窗、蒙板效果實(shí)例代碼
這篇文章主要介紹了Android實(shí)現(xiàn)桌面懸浮窗、蒙板效果實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-05-05Android Studio debug.keystore位置介紹
這篇文章主要介紹了Android Studio debug.keystore位置,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03詳解Android .9.png “點(diǎn)九”圖片的使用
這篇文章主要為大家詳細(xì)介紹了Android .9.png “點(diǎn)九”圖片的使用方法,感興趣的小伙伴們可以參考一下2016-09-09Android第三方開源下拉框NiceSpinner使用詳解
這篇文章主要為大家詳細(xì)介紹了Android第三方開源下拉框NiceSpinner的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07