Android之仿腾讯游戏转盘抽奖

来源:互联网 发布:dos系统下安装windows 编辑:程序博客网 时间:2024/05/16 11:40


-----------------转载请注明出处:http://blog.csdn.net/android_cll

一:先来张效果图(这里应该是GIF动画,我就截屏的所有没有动画,实际是动的):




二:实现步骤:

-------.其实这个挺简单的,就写两个工具类,我把代码贴出来,都有注释,我就不解释什么了、

1.转盘抽奖的工具类:

package cll.com.myapplication;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Rect;import android.graphics.RectF;import android.util.AttributeSet;import android.util.Log;import android.util.TypedValue;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;/** *工具类 */public class BitWheelView extends SurfaceView implements Callback, Runnable {    private SurfaceHolder mHolder;    /**     * 与SurfaceHolder绑定的Canvas     */    private Canvas mCanvas;    /**     * 用于绘制的线程     */    private Thread t;    /**     * 线程的控制开关     */    private boolean isRunning;    /**     * 抽奖的文字     */    private String[] mStrs = new String[]{"单反相机", "IPAD", "恭喜发财", "IPHONE",            "妹子一只", "恭喜发财"};    /**     * 每个盘块的颜色     */    private int[] mColors = new int[]{0xFFFFC300, 0xFFF17E01, 0xFFFFC300,            0xFFF17E01, 0xFFFFC300, 0xFFF17E01};    /**     * 与文字对应的图片     */    private int[] mImgs = new int[]{R.mipmap.danfan, R.mipmap.ipad,            R.mipmap.f040, R.mipmap.iphone, R.mipmap.meizi,            R.mipmap.f040};    /**     * 与文字对应图片的bitmap数组     */    private Bitmap[] mImgsBitmap;    /**     * 盘块的个数     */    private int mItemCount = 6;    /**     * 绘制盘块的范围     */    private RectF mRange = new RectF();    /**     * 圆的直径     */    private int mRadius;    /**     * 绘制盘快的画笔     */    private Paint mArcPaint;    /**     * 绘制文字的画笔     */    private Paint mTextPaint;    /**     * 滚动的速度     */    private double mSpeed;    private volatile float mStartAngle = 0;    /**     * 是否点击了停止     */    private boolean isShouldEnd;    /**     * 控件的中心位置     */    private int mCenter;    /**     * 控件的padding,这里我们认为4个padding的值一致,以paddingleft为标准     */    private int mPadding;    /**     * 背景图的bitmap     */    private Bitmap mBgBitmap = BitmapFactory.decodeResource(getResources(),            R.mipmap.bg2);    /**     * 文字的大小     */    private float mTextSize = TypedValue.applyDimension(            TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());    public BitWheelView(Context context) {        this(context, null);    }    public BitWheelView(Context context, AttributeSet attrs) {        super(context, attrs);        mHolder = getHolder();        mHolder.addCallback(this);        // setZOrderOnTop(true);// 设置画布 背景透明        // mHolder.setFormat(PixelFormat.TRANSLUCENT);        setFocusable(true);        setFocusableInTouchMode(true);        this.setKeepScreenOn(true);    }    /**     * 设置控件为正方形     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = Math.min(getMeasuredWidth(), getMeasuredHeight());        // 获取圆形的直径        mRadius = width - getPaddingLeft() - getPaddingRight();        // padding值        mPadding = getPaddingLeft();        // 中心点        mCenter = width / 2;        setMeasuredDimension(width, width);    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        // 初始化绘制圆弧的画笔        mArcPaint = new Paint();        mArcPaint.setAntiAlias(true);        mArcPaint.setDither(true);        // 初始化绘制文字的画笔        mTextPaint = new Paint();        mTextPaint.setColor(0xFFffffff);        mTextPaint.setTextSize(mTextSize);        // 圆弧的绘制范围        mRange = new RectF(getPaddingLeft(), getPaddingLeft(), mRadius                + getPaddingLeft(), mRadius + getPaddingLeft());        // 初始化图片        mImgsBitmap = new Bitmap[mItemCount];        for (int i = 0; i < mItemCount; i++) {            mImgsBitmap[i] = BitmapFactory.decodeResource(getResources(),                    mImgs[i]);        }        // 开启线程        isRunning = true;        t = new Thread(this);        t.start();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width,                               int height) {    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        // 通知关闭线程        isRunning = false;    }    @Override    public void run() {        // 不断的进行draw        while (isRunning) {            long start = System.currentTimeMillis();            draw();            long end = System.currentTimeMillis();            try {                if (end - start < 50) {                    Thread.sleep(50 - (end - start));                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    private void draw() {        try {            // 获得canvas            mCanvas = mHolder.lockCanvas();            if (mCanvas != null) {                // 绘制背景图                drawBg();                /**                 * 绘制每个块块,每个块块上的文本,每个块块上的图片                 */                float tmpAngle = mStartAngle;                float sweepAngle = (float) (360 / mItemCount);                for (int i = 0; i < mItemCount; i++) {                    // 绘制快快                    mArcPaint.setColor(mColors[i]);//             mArcPaint.setStyle(Style.STROKE);                    mCanvas.drawArc(mRange, tmpAngle, sweepAngle, true,                            mArcPaint);                    // 绘制文本                    drawText(tmpAngle, sweepAngle, mStrs[i]);                    // 绘制Icon                    drawIcon(tmpAngle, i);                    tmpAngle += sweepAngle;                }                // 如果mSpeed不等于0,则相当于在滚动                mStartAngle += mSpeed;                // 点击停止时,设置mSpeed为递减,为0值转盘停止                if (isShouldEnd) {                    mSpeed -= 1;                }                if (mSpeed <= 0) {                    mSpeed = 0;                    isShouldEnd = false;                }                // 根据当前旋转的mStartAngle计算当前滚动到的区域                calInExactArea(mStartAngle);            }        } catch (Exception e) {            e.printStackTrace();        } finally {            if (mCanvas != null)                mHolder.unlockCanvasAndPost(mCanvas);        }    }    /**     * 根据当前旋转的mStartAngle计算当前滚动到的区域 绘制背景,不重要,完全为了美观     */    private void drawBg() {        mCanvas.drawColor(0xFFFFFFFF);        mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding / 2,                mPadding / 2, getMeasuredWidth() - mPadding / 2,                getMeasuredWidth() - mPadding / 2), null);    }    /**     * 根据当前旋转的mStartAngle计算当前滚动到的区域     *     * @param startAngle     */    public void calInExactArea(float startAngle) {        // 让指针从水平向右开始计算        float rotate = startAngle + 90;        rotate %= 360.0;        for (int i = 0; i < mItemCount; i++) {            // 每个的中奖范围            float from = 360 - (i + 1) * (360 / mItemCount);            float to = from + 360 - (i) * (360 / mItemCount);            if ((rotate > from) && (rotate < to)) {                Log.d("TAG", mStrs[i]);                return;            }        }    }    /**     * 绘制图片     *     * @param startAngle     * @param     * @param i     */    private void drawIcon(float startAngle, int i) {        // 设置图片的宽度为直径的1/8        int imgWidth = mRadius / 8;        float angle = (float) ((30 + startAngle) * (Math.PI / 180));        int x = (int) (mCenter + mRadius / 2 / 2 * Math.cos(angle));        int y = (int) (mCenter + mRadius / 2 / 2 * Math.sin(angle));        // 确定绘制图片的位置        Rect rect = new Rect(x - imgWidth / 2, y - imgWidth / 2, x + imgWidth                / 2, y + imgWidth / 2);        mCanvas.drawBitmap(mImgsBitmap[i], null, rect, null);    }    /**     * 绘制文本     *     * @param     * @param startAngle     * @param sweepAngle     * @param string     */    private void drawText(float startAngle, float sweepAngle, String string) {        Path path = new Path();        path.addArc(mRange, startAngle, sweepAngle);        float textWidth = mTextPaint.measureText(string);        // 利用水平偏移让文字居中        float hOffset = (float) (mRadius * Math.PI / mItemCount / 2 - textWidth / 2);// 水平偏移        float vOffset = mRadius / 2 / 6;// 垂直偏移        mCanvas.drawTextOnPath(string, path, hOffset, vOffset, mTextPaint);    }    /**     * 点击开始旋转     *     * @param luckyIndex     */    public void luckyStart(int luckyIndex) {        // 每项角度大小        float angle = (float) (360 / mItemCount);        // 中奖角度范围(因为指针向上,所以水平第一项旋转到指针指向,需要旋转210-270;)        float from = 270 - (luckyIndex + 1) * angle;        float to = from + angle;        // 停下来时旋转的距离        float targetFrom = 4 * 360 + from;        /**         * <pre>         *  (v1 + 0) * (v1+1) / 2 = target ;         *  v1*v1 + v1 - 2target = 0 ;         *  v1=-1+(1*1 + 8 *1 * target)/2;         * </pre>         */        float v1 = (float) (Math.sqrt(1 * 1 + 8 * 1 * targetFrom) - 1) / 2;        float targetTo = 4 * 360 + to;        float v2 = (float) (Math.sqrt(1 * 1 + 8 * 1 * targetTo) - 1) / 2;        mSpeed = (float) (v1 + Math.random() * (v2 - v1));        isShouldEnd = false;    }    public void luckyEnd() {        mStartAngle = 0;        isShouldEnd = true;    }    public boolean isStart() {        return mSpeed != 0;    }    public boolean isShouldEnd() {        return isShouldEnd;    }}
2.九宫格的工具类:

package cll.com.myapplication;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.util.Log;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.view.WindowManager;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import java.util.Random;/** * 九宫格工具类 */public class LuckyView extends LinearLayout implements Runnable,OnTouchListener{   private Context mContext;   private AttributeSet mAttrs;   private int mItemSize = 9;   /**    * 抽奖的文字    */   private String[] mStrs = new String[] { "单反相机", "IPAD", "恭喜发财", "IPHONE",         "妹子一只", "恭喜发财","妹子一只", "恭喜发财","妹子一只" };   /**    * 每个盘块的颜色    */   private int[] mColors = new int[] { 0xFFFFC300, 0xFFF17E01, 0xFFFFC300,         0xFFF17E01, 0xFFFFC300, 0xFFF17E01,0xFFF17E01, 0xFFFFC300, 0xFFF17E01 };   /**    * 与文字对应的图片    */   private int[] mImgs = new int[] { R.mipmap.danfan, R.mipmap.ipad,         R.mipmap.f040, R.mipmap.iphone, R.mipmap.meizi,         R.mipmap.f040 , R.mipmap.iphone, R.mipmap.meizi,         R.mipmap.f040};   public static final int MESSAGE_9 = 9;   public static final int MESSAGE_1 = 1;   public static final int MESSAGE_2 = 2;   public static final int MESSAGE_3 = 3;   public static final int MESSAGE_4 = 4;   public static final int MESSAGE_5 = 5;   public static final int MESSAGE_6 = 6;   public static final int MESSAGE_7 = 7;   public static final int MESSAGE_8 = 8;   public static final int MESSAGE_11 = 11;   public static final int MESSAGE_22 = 22;   public static final int MESSAGE_33 = 33;   public static final int MESSAGE_44 = 44;   public static final int MESSAGE_55 = 55;   public static final int MESSAGE_66 = 66;   public static final int MESSAGE_77 = 77;   public static final int MESSAGE_88 = 88;   public static final int MESSAGE_STOP = 10;   boolean IsLongPressed = false;   int flag = 1;   int number = 8;   TextView tv1;   TextView tv2;   TextView tv3;   TextView tv4;   TextView tv5;   TextView tv6;   TextView tv7;   TextView tv8;   TextView tv9;   ImageView iv;   int width;   int height;   Bitmap wheel;   Bitmap wheel1;   Bitmap wheel2;   Bitmap wheel3;   Bitmap wheel4;   Bitmap wheel5;   Bitmap wheel6;   Bitmap wheel7;   Bitmap wheel8;   Handler handler;   public LuckyView(Context context, AttributeSet attrs, int defStyle) {      super(context, attrs, defStyle);      mContext = context;      mAttrs = attrs;      init();   }   public LuckyView(Context context, AttributeSet attrs) {      super(context, attrs);      mContext = context;      mAttrs = attrs;      init();   }   public LuckyView(Context context) {      super(context);      mContext = context;      init();   }   public void init(){      setOrientation(VERTICAL);      TypedArray array = mContext.obtainStyledAttributes(mAttrs, R.styleable.LuckyView);      mItemSize = array.getInt(R.styleable.LuckyView_size, 0);      View view = LayoutInflater.from(mContext).inflate(R.layout.item, this);      tv1 = (TextView)findViewById(R.id.tv1);      tv2 = (TextView)findViewById(R.id.tv2);      tv3 = (TextView)findViewById(R.id.tv3);      tv4 = (TextView)findViewById(R.id.tv4);      tv5 = (TextView)findViewById(R.id.tv5);      tv6 = (TextView)findViewById(R.id.tv6);      tv7 = (TextView)findViewById(R.id.tv7);      tv8 = (TextView)findViewById(R.id.tv8);      tv9 = (TextView)findViewById(R.id.tv9);      tv1.setBackgroundResource(mImgs[0]);      tv2.setBackgroundResource(mImgs[1]);      tv3.setBackgroundResource(mImgs[2]);      tv4.setBackgroundResource(mImgs[3]);      tv5.setBackgroundResource(mImgs[4]);      tv6.setBackgroundResource(mImgs[5]);      tv7.setBackgroundResource(mImgs[6]);      tv8.setBackgroundResource(mImgs[7]);      tv1.setText(mStrs[0]);      tv2.setText(mStrs[1]);      tv3.setText(mStrs[2]);      tv4.setText(mStrs[3]);      tv5.setText(mStrs[4]);      tv6.setText(mStrs[5]);      tv7.setText(mStrs[6]);      tv8.setText(mStrs[7]);      tv9.setText("Run");      tv9.setOnTouchListener(this);      iv = (ImageView)findViewById(R.id.iv);      WindowManager wm=(WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);      width=wm.getDefaultDisplay().getWidth();       //手机屏幕的宽度      height=wm.getDefaultDisplay().getHeight()+90;      //手机屏幕的高度      wheel = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel);      wheel1 = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel1);      wheel2 = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel2);      wheel3 = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel3);      wheel4 = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel4);      wheel5 = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel5);      wheel6 = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel6);      wheel7 = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel7);      wheel8 = BitmapFactory.decodeResource(getResources(), R.mipmap.wheel8);   }   @Override   public void run() {   }   Handler mHandler = new Handler() {      public void handleMessage(Message msg) {         switch (msg.what) {            case MESSAGE_1:               iv.setImageBitmap(wheel1);               tv1.setText(mStrs[MESSAGE_1-1]);               break;            case MESSAGE_2:               iv.setImageBitmap(wheel2);               tv2.setText(mStrs[MESSAGE_2-1]);               break;            case MESSAGE_3:               iv.setImageBitmap(wheel3);               tv3.setText(mStrs[MESSAGE_3-1]);               break;            case MESSAGE_4:               iv.setImageBitmap(wheel4);               tv4.setText(mStrs[MESSAGE_4-1]);               break;            case MESSAGE_5:               iv.setImageBitmap(wheel5);               tv5.setText(mStrs[MESSAGE_5-1]);               break;            case MESSAGE_6:               iv.setImageBitmap(wheel6);               tv6.setText(mStrs[MESSAGE_6-1]);               break;            case MESSAGE_7:               iv.setImageBitmap(wheel7);               tv7.setText(mStrs[MESSAGE_7-1]);               break;            case MESSAGE_8:               iv.setImageBitmap(wheel8);               tv8.setText(mStrs[MESSAGE_8-1]);               break;            case MESSAGE_11:               flag = 1;//             dialog();               break;            case MESSAGE_22:               flag = 2;//             dialog();               break;            case MESSAGE_33:               flag = 3;//             dialog();               break;            case MESSAGE_44:               flag = 4;//             dialog();               break;            case MESSAGE_55:               flag = 5;//             dialog();               break;            case MESSAGE_66:               flag = 6;//             dialog();               break;            case MESSAGE_77:               flag = 7;//             dialog();               break;            case MESSAGE_88:               flag = 8;//             dialog();               break;            case MESSAGE_STOP:               Bundle bundle = new Bundle();               bundle = msg.getData();               int i = bundle.getInt("msg");               tv9.setText("RUN");               switch (i%8) {                  case 0:                     break;                  case 1:                     break;                  case 2:                     break;                  case 3:                     break;                  case 4:                     break;                  case 5:                     break;                  case 6:                     break;                  case 7:                     break;                  default:                     break;               }               break;         }      }   };   @Override   public boolean onTouch(View v, MotionEvent event) {      Message msg = new Message();      if(event.getAction()==MotionEvent.ACTION_DOWN){         //zhongjian         tv9.setText("RUNNING");         Random random = new Random();         number = random.nextInt((8))+1;         Log.i("chz",""+number);         new Thread(new Runnable() {            public void run() {               Random random = new Random();               int num = random.nextInt((8));               Log.i("chz",""+(num+3));               while(number<60+num){                  Message message = new Message();                  switch (number%8) {                     case 0:                        message.what = MESSAGE_8;                        break;                     case 1:                        message.what = MESSAGE_1;                        break;                     case 2:                        message.what = MESSAGE_2;                        break;                     case 3:                        message.what = MESSAGE_3;                        break;                     case 4:                        message.what = MESSAGE_4;                        break;                     case 5:                        message.what = MESSAGE_5;                        break;                     case 6:                        message.what = MESSAGE_6;                        break;                     case 7:                        message.what = MESSAGE_7;                        break;                     case 8:                        message.what = MESSAGE_8;                        break;                     default:                        break;                  }                  number++;//                 Bundle bundle = new Bundle();//                  bundle.putString("msg", "chzlovehp");//                  message.setData(bundle);                  mHandler.sendMessage(message);                  if(number<50){                     try {                        Thread.sleep(100);                     } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                     }                  }else if(number>50 && number<60){                     try {                        Thread.sleep(300);                     } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                     }                  }else{                     try {                        Thread.sleep(400);                     } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                     }                  }               }               Message message = new Message();               message.what = MESSAGE_STOP;               Bundle bundle = new Bundle();               bundle.putInt("msg", (num+3));               message.setData(bundle);               mHandler.sendMessage(message);            }         }).start();         mHandler.sendMessage(msg);      }      return false;   }}

------------------就那么简单,有不懂得自己下demo看,不喜勿喷、

------------------demo地址:点击打开链接


7 0
原创粉丝点击