-----------------转载请注明出处: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; /** **/ 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.九宫格的工具类:* (v1 + 0) * (v1+1) / 2 = target ; * v1*v1 + v1 - 2target = 0 ; * v1=-1+(1*1 + 8 *1 * target)/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地址:点击打开链接