android刮刮卡实现

这个是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();
            }
        }
    }
}

 

posted @ 2014-12-18 11:36  宋文  阅读(355)  评论(0编辑  收藏  举报