这个是2年前的东西了,当时没有加注释,先上个源码,以后在补充吧!
用法:
1、setBitmapSurface 方法来设置刮刮卡的上层的图片
2、setTouch 开关是否可以刮
3、setOnLotteryListener 已经刮开的回调
4、playsound 是播放在刮刮刮卡过程中的声音,可以去掉
5、设置奖区奖品有2中方法:A、重叠一个View在GuaGuaKaView下面。B、直接setBackgroud也可以
源码:
@SuppressLint("DrawAllocation") public class GuaGuaKaView extends ImageView { private Bitmap mImgBitmap = null; private RectF mImgDesRect; private Bitmap mEraseMaskBitmap = null; private Canvas mCanvas = null; private Paint mErasePaint = null; private Path mErasePath = null; private float mX, mY; private int paint_width = 40; private boolean isKaijiang = false; private Context context; private boolean isTouch = true; private static final float TOUCH_TOLERANCE = 4; private boolean isPlaySound = true; private ArrayList<Bitmap> list_bm; private Handler handler = new Handler(); public GuaGuaKaView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub this.context = context; init(); } public GuaGuaKaView(Context context) { super(context); // TODO Auto-generated constructor stub this.context = context; init(); } private void init() { initErasePaint(); list_bm = new ArrayList<Bitmap>(); } public void setBitmapSurface(final Bitmap bm) { mImgBitmap = bm; mImgDesRect = new RectF(0, 0, mImgBitmap.getWidth(), mImgBitmap.getHeight()); initBmpMask(); } public void setBitmapSurface(int res) { // Bitmap bm = BitmapFactory.decodeResource(getResources(), res); setBitmapSurface(ImageUtils.getSmallBitmap(getResources(), res)); } public void setTouch(boolean isTouch) { this.isTouch = isTouch; } public void setPlaySound(boolean isPlaySound) { this.isPlaySound = isPlaySound; } private void initBmpMask() { if (mImgDesRect != null) { int w = (int) mImgDesRect.width(); int h = (int) mImgDesRect.height(); if (mEraseMaskBitmap == null) { mEraseMaskBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); mEraseMaskBitmap.eraseColor(Color.TRANSPARENT); } } if (mEraseMaskBitmap != null) mCanvas = new Canvas(mEraseMaskBitmap); } private void initErasePaint() { mErasePaint = new Paint(); mErasePaint.setAntiAlias(true); mErasePaint.setDither(true); mErasePaint.setColor(0xFF000000); mErasePaint.setStyle(Paint.Style.STROKE); mErasePaint.setStrokeJoin(Paint.Join.ROUND); mErasePaint.setStrokeCap(Paint.Cap.ROUND); mErasePaint.setStrokeWidth(paint_width); mErasePaint.setXfermode(null); mErasePath = new Path(); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); if (mImgBitmap != null) { Paint paint = new Paint(); Rect rect = new Rect(0, 0, getWidth(), getHeight()); int sc = canvas.saveLayer(rect.left, rect.top, rect.right, mImgDesRect.bottom, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR)); canvas.drawBitmap(mImgBitmap, new Rect(0, 0, mImgBitmap.getWidth(), mImgBitmap.getHeight()), rect, null); canvas.drawBitmap(mEraseMaskBitmap, new Rect(0, 0, mEraseMaskBitmap.getWidth(), mEraseMaskBitmap.getHeight()), rect, paint); paint.setXfermode(null); canvas.restoreToCount(sc); } } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if (!isTouch) { return true; } if (mImgDesRect == null) { return false; } if (isKaijiang) { return false; } int action = event.getAction(); float x = event.getX() - mImgDesRect.left; float y = event.getY() - mImgDesRect.top; switch (action) { case MotionEvent.ACTION_DOWN: mErasePath.reset(); mErasePath.moveTo(x, y); mX = x; mY = y; invalidate(); break; case MotionEvent.ACTION_MOVE: float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mErasePath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; // commit the path to offscreen mCanvas.drawPath(mErasePath, mErasePaint); if (isPlaySound) { if (player == null || !player.isPlaying()) { playSound(R.raw.ggk_xz); } } } invalidate(); // refresh if (getScratchPercentage() > 0.7f && onLotteryListener != null) { isKaijiang = true; onLotteryListener.onLottery(); } break; case MotionEvent.ACTION_UP: mErasePath.lineTo(mX, mY); mCanvas.drawPath(mErasePath, mErasePaint); mErasePath.reset(); invalidate(); break; } return true; } /** * 取得图片刮开的百分比, 没20个像素取一下 * * @return */ private float getScratchPercentage() { // int start_heigth = (int) ( (getHeight() / 4.4f) * 3.4); int start_heigth = 0; int width = mEraseMaskBitmap.getWidth(); int heigth = mEraseMaskBitmap.getHeight(); int diff = paint_width / 2; int point_count = 0; int count = 0; for (int i = diff; i < width; i += diff) { for (int j = diff + start_heigth; j < heigth; j += diff) { if (mEraseMaskBitmap.getPixel(i, j) == 0xff000000) { count++; } point_count++; } } return (float) count / point_count; } private OnLotteryListener onLotteryListener; public void setOnLotteryListener(OnLotteryListener l) { this.onLotteryListener = l; } public interface OnLotteryListener { public void onLottery(); } private MediaPlayer player; private void playSound(int resid) { if (player == null) { player = MediaPlayer.create(this.context, resid); } if (player != null) player.start(); } @SuppressWarnings("deprecation") public void recycle() { setImageBitmap(null); setBackgroundDrawable(null); for (int i = 0; list_bm != null && i < list_bm.size(); i++) { Bitmap bm = list_bm.get(i); if (bm != null) { bm.recycle(); } } } }