最近在公司做商城项目,遇到了需要中奖一样的刮刮乐项目。二话不说,先看效果:
一、新建自定义的view,继承textView
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;
import android.widget.Toast;
public class GuaGuaView extends TextView {
private Context mContext;
private static final String TAG = "ScratchTextView";
private Bitmap mbitmap;// 盖在字上面的图片
private Canvas mCanvas; //画线的画布
private Paint mPaint;//划线的画笔
private Path mPath;//线
private float mX, mY;
private float TOUCH_TOLERANCE;
private boolean isInited = false;//用于判断时候覆盖了textview的文字
private int WIDTH;
private int HEIGHT;
private boolean mHasOpen = false;
private int openSize;
public GuaGuaView(Context context) {
super(context);
}
public GuaGuaView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GuaGuaView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//onDraw初始化的时候调用一次,然invalidate()的时候调用,
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInited) {
mCanvas.drawPath(mPath, mPaint);//把线画到mCanvas上,mCanva会把线画到mBitmap
canvas.drawBitmap(mbitmap, 0, 0, null);// 把mBitmap画到textview上 canvas是父textvie传过来的。
}
}
/**
* 初始化刮刮卡
*
* @param bgColor 刮刮卡背景色,用于盖住下面的字
* @param paintStrokeWidth 擦除线宽
* @param touchTolerance 画线容差
*/
public void initScratchCard(Context context, final int bgColor, final int paintStrokeWidth, float touchTolerance) {
mContext=context;
TOUCH_TOLERANCE = touchTolerance;
mPaint = new Paint();//创建画笔
mPaint.setAlpha(240);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));//
mPaint.setAntiAlias(true);// 抗锯齿
mPaint.setDither(true);// 防抖动
mPaint.setStyle(Paint.Style.STROKE);// 画笔类型: STROKE空心 FILL实心 FILL_AND_STROKE用契形填充
mPaint.setStrokeJoin(Paint.Join.ROUND);// 画笔接洽点类型
mPaint.setStrokeCap(Paint.Cap.ROUND);// 画笔笔刷类型
mPaint.setStrokeWidth(paintStrokeWidth);// 画笔笔刷宽度
mPath = new Path();
mbitmap = Bitmap.createBitmap(getLayoutParams().width, getLayoutParams().height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mbitmap);//通过bitmap生成一个画布
Paint paint = new Paint();//用于绘制生成的背景图片的字体
paint.setTextSize(50);
paint.setColor(getResources().getColor(R.color.white));
mCanvas.drawColor(bgColor);
mCanvas.drawText("刮开抽奖", getLayoutParams().width/5, getLayoutParams().height/2, paint);
WIDTH=mbitmap.getWidth();
HEIGHT=mbitmap.getHeight();
isInited = true;
Thread thread = new Thread(mRunnable);
thread.start();
}
//该触膜事件可以定义在调用的activity中实现
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isInited) {
return true;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.reset(); // 重置绘制路线,即隐藏之前绘制的轨迹
mPath.moveTo(event.getX(), event.getY()); // mPath绘制的绘制起点
mX = event.getX();
mY = event.getY();
invalidate();//更新界面
Log.d(TAG, mX + "|" + mY);
break;
case MotionEvent.ACTION_MOVE:
//x和y移动的距离
float dx = Math.abs(event.getX() - mX);
float dy = Math.abs(event.getY() - mY);
//x,y移动的距离大于画线容差
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
// 二次贝塞尔,实现平滑曲线;mX, mY为操作点,(x + mX) / 2, (y + mY) / 2为终点
mPath.quadTo(mX, mY, (event.getX() + mX) / 2, (event.getY() + mY) / 2);
// 第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值
mX = event.getX();
mY = event.getY();
Log.d(TAG, mX + "|" + mY);
invalidate();
break;
}
}
return true;
}
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
while (!mHasOpen) {
SystemClock.sleep(100);
float totalArea = WIDTH * HEIGHT;
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
int pixel = mbitmap.getPixel(i, j);
if (pixel == 0) {
openSize++;
}
}
}
if (openSize/ totalArea >0.001f) {
mHandler.sendEmptyMessage(0);
}
openSize = 0;
}
}
};
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
Toast.makeText(mContext, "已经刮开了", Toast.LENGTH_SHORT).show();
mHasOpen = true;
}
};
}
二、xml文件
<com.example.administrator.guaguaprice_master.GuaGuaView
android:id="@+id/tv_Scratch"
android:layout_width="200dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:background="#ffffff"
android:gravity="center"
android:maxLines="1"
android:text="iPhone6s"
android:textColor="#000000"
android:textSize="20sp" />
三、main文件
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
//刮刮乐图
private GuaGuaView guaGuaView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
guaGuaView = (GuaGuaView) findViewById(R.id.tv_Scratch);
guaGuaView.initScratchCard(this, 0xFFCECED1, 20, 1f);
guaGuaView.setText("一等奖");
}
}