android 刮开文字,直接拿来用的Android刮奖控件

直接上效果图

7f38d9c2d4fccc341ebe6b4fc9ced7bd.png

功能特色: 1、可以设置刮开后显示文字或图片

2、可以统计已刮开区域所占百分比

下面是源码:

@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;

}

}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值