直接拿來用的Android刮獎控件
更新時間:2016年09月05日 15:47:39 作者:cmeiyuan
這篇文章主要為大家分享了可以直接拿來用的Android刮獎控件,非常棒的刮獎控件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
直接上效果圖

功能特色:
1、可以設(shè)置刮開后顯示文字或圖片
2、可以統(tǒng)計已刮開區(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ào)用
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);
}
// 手指在屏幕上滑動時調(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è)置貝塞爾曲線的操作點為起點和終點的一半
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) {
// 二次貝塞爾,實現(xiàn)平滑曲線;cX, cY為操作點 x,y為終點
mPath.quadTo(cX, cY, x, y);
// 第二次執(zhí)行時,第一次結(jié)束調(diào)用的坐標值將作為第二次調(dià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);
// 收到計算命令,立即開始計算
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;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android AccessibilityService實現(xiàn)微信搶紅包插件
這篇文章主要介紹了Android AccessibilityService實現(xiàn)微信搶紅包插件的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11
Android_UI 仿QQ側(cè)滑菜單效果的實現(xiàn)
相信大家對QQ側(cè)滑菜單的效果已經(jīng)不陌生了吧,側(cè)滑進入個人頭像一側(cè),進行對頭像的更改,我的收藏,QQ錢包,我的文件等一系列的操作,下面小編給大家分享Android_UI 仿QQ側(cè)滑菜單效果的實現(xiàn),一起看看吧2017-04-04
Rxjava2_Flowable_Sqlite_Android數(shù)據(jù)庫訪問實例
下面小編就為大家分享一篇Rxjava2_Flowable_Sqlite_Android數(shù)據(jù)庫訪問實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02

