android刮奖控件,使用简单。
16lz
2021-12-04
序言:
很多哥们可能不喜欢买彩票,但是小时候肯定都刮过奖,5毛钱一次,今天我们要在android上面实现刮奖的控件。
功能:
奖的生成,刮奖,刮开面积的计算,分享到第三方平台。
效果图:
控件代码:
package com.example.xiangpica;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Path;import android.graphics.PorterDuff.Mode;import android.graphics.PorterDuffXfermode;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.TextView;import com.example.xiangpica.bean.LotteryInfo;import com.example.xiangpica.manage.LotteryManage;public class MyView extends TextView {private int widget, height;private Context mContext;private Paint mPaint;private Canvas tempCanvas;private Bitmap mBitmap;private float x, y, ox, oy;private Path mPath;Handler mHandler;MyThread mThread;LotteryInfo info;int messageCount;int[] pixels;int color = 0xFFD6D6D6;public MyView(Context context, AttributeSet attrs) {super(context, attrs);mContext = context;init(attrs);}/** * 再一次抽奖 */public void againLotter() {messageCount = 0;info = LotteryManage.getRandomLottery();tempCanvas.drawColor(color);setText(info.getText());}public LotteryInfo getLotterInfo() {return info;}private void init(AttributeSet attrs) {// 获取控件大小值TypedArray a = mContext.obtainStyledAttributes(attrs,R.styleable.lotter);widget = (int) a.getDimension(R.styleable.lotter_widget, 300);height = (int) a.getDimension(R.styleable.lotter_height, 100);a.recycle();// 初始化路径mPath = new Path();// 初始化画笔mPaint = new Paint();mPaint.setColor(mContext.getResources().getColor(R.color.view_color));mPaint.setAlpha(0);mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));mPaint.setAntiAlias(true);mPaint.setStyle(Style.STROKE);mPaint.setStrokeWidth(50);//画笔宽度// 初始化Bitmap并且锁定到临时画布上mBitmap = Bitmap.createBitmap(widget, height, Bitmap.Config.ARGB_4444);tempCanvas = new Canvas();tempCanvas.setBitmap(mBitmap);againLotter();// 在字线程中创建Handler接收像素消息mThread = new MyThread();mThread.start();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 将处理过的bitmap画上去canvas.drawBitmap(mBitmap, 0, 0, null);}@Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();switch (action) {case MotionEvent.ACTION_DOWN:touchDown(event);break;case MotionEvent.ACTION_MOVE:touchMove(event);break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:break;}return true;}/** * 移动的时候 * @param event */private void touchMove(MotionEvent event) {x = event.getX();y = event.getY();// 二次贝塞尔,实现平滑曲线;oX, oY为操作点 x,y为终点 mPath.quadTo((x + ox) / 2, (y + oy) / 2, x, y);tempCanvas.drawPath(mPath, mPaint);ox = x;oy = y;invalidate();computeScale();}/** * 第一次按下来 * * @param event */private void touchDown(MotionEvent event) {ox = x = event.getX();oy = y = event.getY();mPath.reset();mPath.moveTo(ox, oy);}/** * 计算百分比 */private void computeScale() {Message msg = mHandler.obtainMessage(0);msg.obj = ++messageCount;mHandler.sendMessage(msg);}/** * 异步线程,作用是创建handler接收处理消息。 * @author Administrator * */class MyThread extends Thread {public MyThread() {}@Overridepublic void run() {super.run();/* * 创建 handler前先初始化Looper. */Looper.prepare();mHandler = new Handler() {@Overridepublic void dispatchMessage(Message msg) {super.dispatchMessage(msg);// 只处理最后一次的百分比if ((Integer) (msg.obj) != messageCount) {return;}// 取出像素点synchronized (mBitmap) {if (pixels == null) {pixels = new int[mBitmap.getWidth()* mBitmap.getHeight()];}mBitmap.getPixels(pixels, 0, widget, 0, 0, widget,height);}int sum = pixels.length;int num = 0;for (int i = 0; i < sum; i++) {if (pixels[i] == 0) {num++;}}info.setScratchPercentage(num / (double) sum);System.out.println("百分比:" + info.getScratchPercentage()* 100);}};/* * 启动该线程的消息队列 */Looper.loop();}}}
原理介绍:
1、刮彩票的实现,新建一张和控件一样大的Bitmap,然后根据此bitmap新建一个临时画布并设置此bitmap,这样子临时画布做的操作就会更改到这张bitmap上面,然后重写控件的ondraw方法每次都去draw这张bitmap即可。
2、刮开面积的计算,由于bitmap的表面区域随着刮的过程要不断计算太耗时,所以计算面积是异步进行的,再异步线程初始化handler,然后刮开部分有改变就通知handler去计算并发送计算的次数,handler计算的时候会判断是否是最后一次,如果不是就直接不算,这样的好处是刮开的过程中会不断的发送,只有最后一次发送的计算通知是有效的值,计算的原理就是拷贝出bitmap的像素值,然后遍历判断是0的像素点比例(为0的就是透明区域)。
3、奖品生成原理,采用随机数,0~1000,0~9是一等奖(概率1%)10~29是二等奖(概率2%)30~100是三等奖(概率7%)
4、分享控件的原理,博主之前的博客http://blog.csdn.net/panjidong_3/article/details/16943063有详细介绍,很方便直接拿来用。
下载:
刮刮乐:http://download.csdn.net/detail/panjidong_3/6703273
更多相关文章
- android之控件EditText学习
- Android布局属性补遗
- ui布局参数设置
- layout_alignParentRight android:paddingRight
- Android练习
- C虾仔笔记 - EditText编辑框
- android 5.0系统 EditText控件
- Android布局控件属性
- android layout以及一些常用的android控件属性