zoukankan      html  css  js  c++  java
  • Android实现抽奖转盘

    一、SurfaceView认识及的应用的思路

    • SurfaceView继承自(extends)View,View是在UI线程中进行绘制;
    • 而SurfaceView是在一个子线程中对自己进行绘制,优势:避免造成UI线程阻塞;
    • SurfaceView中包含一个专门用于绘制的Surface,Surface中包含一个Canvas;
    • 获得Canvas:可以从SurfaceView中方法的getHolder()获得SurfaceHolder,从holder获得Canvas;
    • holder还管理着SurfaceView的生命周期

             ①surfaceCreated()创建子线程,子线程的run()方法中开启SurfaceView的绘制。

             ②surfaceChanged()

               surfaceDestoryed()中关闭子线程。

    二、SurfaceView的一般写法

     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

    三、代码编写

    • 绘制抽奖转盘的盘快
    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

    四、抽奖转盘的秘密

     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
  • 相关阅读:
    渗透利器-kali工具 (第四章-4) 学习python强大的第三方库
    渗透利器-kali工具 (第四章-3) Python数据结构学习
    渗透利器-kali工具 (第四章-2) python循环判断分支语句与异常处理
    渗透利器-kali工具 (第四章-1) Python环境安装与基本语法
    渗透利器-kali工具 (第三章-7) webshell管理工具
    渗透利器-kali工具 (第三章-6) Xss漏洞学习之-Beef-Xss
    php面试笔记(6)-php基础知识-正则表达式考点
    php利用七牛云的对象存储完成图片上传-高效管理图片
    将Markdown编辑器搬进您的博客-让我们更优雅的书写文章
    踩坑ThinkPHP5之模型对象返回的数据集如何转为数组
  • 原文地址:https://www.cnblogs.com/wucaiyun1/p/4923444.html
Copyright © 2011-2022 走看看