Android实现刮刮卡抽奖(上)
自定义View实现刮刮卡界面:
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* 自定义一个刮刮卡view
* @description:
* @date 2015-12-3 上午9:27:06
*/
@SuppressLint(“DrawAllocation”)
public class ScratchCardView extends View {
private Paint mPaint;// 画笔private Path mPath;// 绘制路径private Canvas mCanvas;// 画面Canvasprivate int mCurrentX;// 手指移动后X位置private int mCurrentY;// 手指移动后Y位置private Bitmap mTopBitmap;// 位于上层图片private String mTextStr;// 卡片上的文字private Paint mTextPaint;// 画文字的画笔private Rect mTextRect;// 文字对应的矩形框Rectprivate volatile boolean isFinish = false;// 判断遮盖层是否被用户消除达到一定的范围(阙值)private OnScratchCardFinishListener mCardFinishListener;//刮完成后回调接口public interface OnScratchCardFinishListener {// 图层刮完后回调接口 void onFinish(String result);}// 设置回调public void setCardFinishListener(OnScratchCardFinishListener mCardFinish) { this.mCardFinishListener = mCardFinish;}public ScratchCardView(Context context) { this(context, null, 0);}public ScratchCardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initViewsParams();}public ScratchCardView(Context context, AttributeSet attrs) { this(context, attrs, 0);}/** * 初始化相关数据及参数 * @description: * @date 2015-12-3 上午9:26:48 */private void initViewsParams() { mPath = new Path(); mPaint = new Paint(); mTextStr = "500万现金"; mTextPaint = new Paint(); mTextRect = new Rect();}private void setTextPaint() { mTextPaint.setColor(Color.RED);// 设置颜色 mTextPaint.setStyle(Style.FILL);// 设置画笔样式为填充 mTextPaint.setTextSize(40); mTextPaint.getTextBounds(mTextStr, 0, mTextStr.length(), mTextRect);// 获得当前文字的宽高信息}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = getMeasuredWidth();// 获取到宽度 int height = getMeasuredHeight();// 获取到高度 mTopBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);// 根据参数创建新位图 mCanvas = new Canvas(mTopBitmap); // 设置绘画文字的画笔 参数 setTextPaint(); // 设置画笔参数 setBitmapPaint(); mCanvas.drawColor(Color.parseColor("#c0c0c0"));}private void setBitmapPaint() { mPaint.setColor(Color.GREEN);// 设置颜色 mPaint.setAntiAlias(true);// 设置抗紧锯齿 mPaint.setDither(true);// 防抖动 mPaint.setStrokeJoin(Paint.Join.ROUND);// 设置图形结合处的样子 mPaint.setStrokeCap(Paint.Cap.ROUND);// 设置画笔的图形样式,如圆形样式 mPaint.setStyle(Style.STROKE);// 设置画笔样式为空心 mPaint.setStrokeWidth(20);// 设置画笔粗细}@Overridepublic boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); int x = (int) event.getX();// 当前x int y = (int) event.getY();// 当前y switch (action) { case MotionEvent.ACTION_DOWN: mCurrentX = x; mCurrentY = y; mPath.moveTo(mCurrentX, mCurrentY);// 移动Path break; case MotionEvent.ACTION_MOVE: int dx = Math.abs(x - mCurrentX); int dy = Math.abs(y - mCurrentY); if (dx > 3 || dy > 3) { mPath.lineTo(x, y); } mCurrentX = x; mCurrentY = y; break; case MotionEvent.ACTION_UP: new Thread(mCardRunble).start();//开启子线程进行计算 break; default: break; } invalidate();//主线程中调用invalidate()请求重绘View树,即draw()过程 return true;}@Overrideprotected void onDraw(Canvas canvas) { canvas.drawText(mTextStr, getWidth() / 2 - mTextRect.width() / 2, getHeight() / 2 + mTextRect.height() / 2, mTextPaint); if (!isFinish) { mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT));// ProterDuffXfermode用法可以参考:http://www.2cto.com/kf/201504/388144.html mCanvas.drawPath(mPath, mPaint); canvas.drawBitmap(mTopBitmap, 0, 0, null); } else { if (mCardFinishListener != null) { mCardFinishListener.onFinish(mTextStr); } }}private Runnable mCardRunble = new Runnable() { @Override public void run() { int w = getWidth(); int h = getHeight(); float wipeArea = 0; float totalArea = w * h; Bitmap bitmap = mTopBitmap; int[] 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);// 获取百分比 if (percent > 60) { isFinish = true; postInvalidate();//子线程中调用invalidate()请求重绘View树,即draw()过程 } } }};
}
在Activity中使用,关键是要回调刮奖完毕的回调接口OnScratchCardFinishListener中的方法:
public class MainActivity extends Activity {
private ScratchCardView mCardView;
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mCardView = (ScratchCardView) findViewById(R.id.card_view); mCardView.setCardFinishListener(new OnScratchCardFinishListener() { @Override public void onFinish(String result) { Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();//回调时把显示的文字也Toast出来! } });}
}
布局很简单,就是加了一个我们自定义的ScrtchCardView:
更多相关文章
- 闹铃设置
- android使用shape设置下边框
- android camera的基本使用
- android 设置linelayout让按钮自动适应屏大小
- Android(安卓)实现拍照功能
- Android(安卓)字体效果:描边、浮雕效果
- 【有图】android通过jdbc连接mysql(附文件)
- android 入门demo 解析xml
- Android(安卓)将TabHost放在最下方显示