Android之仿腾讯游戏转盘抽奖


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

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

Android之仿腾讯游戏转盘抽奖_第1张图片

Android之仿腾讯游戏转盘抽奖_第2张图片

Android之仿腾讯游戏转盘抽奖_第3张图片

二:实现步骤:

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

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;
        /**
         * 
         *  (v1 + 0) * (v1+1) / 2 = target ;
         *  v1*v1 + v1 - 2target = 0 ;
         *  v1=-1+(1*1 + 8 *1 * target)/2;
         * 
*/ 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地址:点击打开链接


你可能感兴趣的:(Android进阶)