Android實現抽獎轉盤

1、SurfaceView認識及的應用的思路java

  • SurfaceView繼承自(extends)View,View是在UI線程中進行繪製;
  • 而SurfaceView是在一個子線程中對本身進行繪製,優點:避免形成UI線程阻塞;
  • SurfaceView中包含一個專門用於繪製的Surface,Surface中包含一個Canvas;
  • 得到Canvas:能夠從SurfaceView中方法的getHolder()得到SurfaceHolder,從holder得到Canvas;
  • holder還管理着SurfaceView的生命週期

         ①surfaceCreated()建立子線程,子線程的run()方法中開啓SurfaceView的繪製。android

         ②surfaceChanged()canvas

           surfaceDestoryed()中關閉子線程。windows

2、SurfaceView的通常寫法dom

 1 package com.example.luckypan;
 2 
 3 import android.content.Context;
 4 import android.graphics.Canvas;
 5 import android.util.AttributeSet;
 6 import android.view.SurfaceHolder;
 7 import android.view.SurfaceHolder.Callback;
 8 import android.view.SurfaceView;
 9 
10 public class SurfaceViewTemplate extends SurfaceView implements Callback, Runnable {
11 
12     private SurfaceHolder mHolder;
13     private Canvas mCanvas;
14     /**
15      * 用於繪製線程
16      */
17     private Thread thread;
18     /**
19      * 線程的控制開關
20      */
21     private boolean isRunning;
22     public SurfaceViewTemplate(Context context) {
23         this(context, null);
24     }
25     public SurfaceViewTemplate(Context context, AttributeSet attrs) {
26         super(context, attrs);
27         mHolder=getHolder();
28         mHolder.addCallback(this);
29         //可得到焦點
30         setFocusable(true);
31         setFocusableInTouchMode(true);
32         //設置常量
33         setKeepScreenOn(true);
34     }
35     public void surfaceCreated(SurfaceHolder holder) {
36         isRunning=true;
37         thread=new Thread(this);
38         thread.start();
39         
40     }
41     public void surfaceChanged(SurfaceHolder holder, int format, int width,
42             int height) {
43         // TODO Auto-generated method stub
44         
45     }
46     public void surfaceDestroyed(SurfaceHolder holder) {
47         isRunning=false;
48         
49     }
50     public void run() {
51         //不斷進行繪製
52         while (isRunning)
53         {
54             draw();
55         }
56     }
57     private void draw() {
58         try {
59             mCanvas=mHolder.lockCanvas();
60             if (mCanvas!=null) {
61                 //
62             }
63         }
64         catch (Exception e) {
65         
66         }
67         finally
68         {
69             if (mCanvas!=null) {
70                 mHolder.unlockCanvasAndPost(mCanvas);
71             }
72         }
73     }
74 
75 
76 }
SurfaceViewTemplate

3、代碼編寫eclipse

  • 繪製抽獎轉盤的盤快
  1.         繪製背景:drawBg(), Canvas的兩個方法:drawColor(color the color to draw onto the canvas),這裏我設置背景色爲白色0xFFFFFFFF、drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint),這個bitmap是背景圖片,背景是一個矩形new Rect(),其餘參數設置爲null。
    1. 1 private void drawBg() {
      2         mCanvas.drawColor(0xFFFFFFFF);
      3         mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding/2, mPadding/2, getMeasuredWidth()-mPadding/2, getMeasuredHeight()-mPadding/2), null);
      4     }
      drawBg
  2. 繪製盤快:
1 //繪製盤快
2                 float tmpAngle=mStartAngle;
3                 float sweepAngle=360/mItemCount;
4                 for (int i = 0; i < mItemCount; i++) {
5                     mArcPaint.setColor(mColor[i]);
6                     //繪製盤快
7                     mCanvas.drawArc(mRange, tmpAngle, sweepAngle,true, mArcPaint);
View Code
  • 繪製抽獎轉盤的獎項文字
 1 /**
 2      * 繪製每一個盤快的文本
 3      * @param tmpAngle
 4      * @param sweepAngle
 5      * @param string
 6      */
 7     private void drawText(float tmpAngle, float sweepAngle, String string) {
 8         Path path=new Path();
 9         path.addArc(mRange, tmpAngle, sweepAngle);
10         //利用水平偏移量讓文字居中
11         float textWidth=mTextPaint.measureText(string);
12         int hOffset=(int) (mRadius*Math.PI/mItemCount/2-textWidth/2);
13         int vOffset=mRadius/2/6;//垂直偏移量
14         mCanvas.drawTextOnPath(string, path, hOffset, vOffset, mTextPaint);
15     }
drawText
  • 繪製抽獎轉盤的圖片
 1 /**
 2      * 繪製圖片
 3      * @param tmpAngle
 4      * @param bitmap
 5      */
 6     private void drawIcon(float tmpAngle, Bitmap bitmap) {
 7         //設置圖片的寬度爲直徑的1/8
 8         int imgWidth=mRadius/8;
 9         float angle=(float) ((tmpAngle+360/mItemCount/2)*Math.PI/180);
10         int x=(int) (mCenter+mRadius/2/2*Math.cos(angle));
11         int y=(int) (mCenter+mRadius/2/2*Math.sin(angle));
12         //肯定圖片位置
13         Rect rect=new Rect(x-imgWidth/2, y-imgWidth/2, x+imgWidth/2, y+imgWidth/2);
14         mCanvas.drawBitmap(bitmap, null, rect,null);
15     }
drawIcon
  • 轉盤滾動及設置中止的指向
 1 private void draw() {
 2         try {
 3             mCanvas=mHolder.lockCanvas();
 4             if (mCanvas!=null) {
 5                 //繪製背景
 6                 drawBg();
 7                 //繪製盤快
 8                 float tmpAngle=mStartAngle;
 9                 float sweepAngle=360/mItemCount;
10                 for (int i = 0; i < mItemCount; i++) {
11                     mArcPaint.setColor(mColor[i]);
12                     //繪製盤快
13                     mCanvas.drawArc(mRange, tmpAngle, sweepAngle,true, mArcPaint);
14                     //繪製文本
15                     drawText(tmpAngle,sweepAngle,mStrings[i]);
16                     //繪製圖片
17                     drawIcon(tmpAngle,mImagBitmaps[i]);
18                     tmpAngle+=sweepAngle;
19                 }
20                 mStartAngle+=mSpeed;
21                 //判斷是否點擊中止按鈕
22                 if (isShouldEnd) {
23                     mSpeed-=1;
24                 }
25                 if (mSpeed<=0)
26                 {
27                     mSpeed=0;
28                     isShouldEnd=false;
29                 }
30             }
31         }
32         catch (Exception e) {
33         
34         }
35         finally
36         {
37             if (mCanvas!=null) {
38                 mHolder.unlockCanvasAndPost(mCanvas);
39             }
40         }
41     }
draw

4、抽獎轉盤的祕密ide

 1 /**
 2      * 電機啓動旋轉
 3      * 控制指定盤快中止範圍
 4      * @param index
 5      */
 6     public void luckyStart(int index)
 7     {
 8         //計算每一項的角度
 9         float angle=360/mItemCount;
10         //計算每一項的中獎範圍
11         //1->150~210
12         //0->210~270
13         float from=270-(index+1)*angle;
14         float end=from+angle;
15     //        設置停下來須要旋轉的距離
16         float targetFrom=4*360+from;
17         float targetEnd=4*360+end;
18         /**
19          * <pre>
20          * v1->0 且每次-1
21          * (v1+0)*(v1+1)/2=targetFrom 等差數列求和公式;
22          * v1*v1+v1-2*targetFrom=0;
23          * v1=(-1+Math.sqrt(1+8*targetFrom))/2 一元二次方程求根公式
24          * </pre>
25          */
26         float v1=(float) ((-1+Math.sqrt(1+8*targetFrom))/2);
27         float v2=(float) ((-1+Math.sqrt(1+8*targetEnd))/2);
28         mSpeed=v1+Math.random()*(v2-v1);
29 //        mSpeed=v2;
30         isShouldEnd=false;
31     }
luckyStart
相關文章
相關標籤/搜索