安卓 刮奖效果

刮奖类

package com.example.prizedemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.TextView;

/**
 * 功能:
 * @author: zhaoxin
 * @version 创建时间:2014-10-19上午10:33:44
 */
public class Gua 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 Gua(Context context) {
        super(context);
        init(context);
    }

    public Gua(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(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;
    }
}


activity中应用


gua = (Gua) findViewById(R.id.gua);
        gua.setText("恭喜中奖");
        gua.setOnWipeListener(new onWipeListener() {

            @Override
            public void onWipe(int percent) {
                if (percent > 70) {
                    Toast.makeText(getApplicationContext(), "=完成=" + percent,
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getApplicationContext(), "继续努力" + percent,
                            Toast.LENGTH_SHORT).show();
                }
            }
        });

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值