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的一般写法
package com.example.luckypan; import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView; public class SurfaceViewTemplate extends SurfaceView implements Callback, Runnable { private SurfaceHolder mHolder;
private Canvas mCanvas;
/**
* 用于绘制线程
*/
private Thread thread;
/**
* 线程的控制开关
*/
private boolean isRunning;
public SurfaceViewTemplate(Context context) {
this(context, null);
}
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
mHolder=getHolder();
mHolder.addCallback(this);
//可获得焦点
setFocusable(true);
setFocusableInTouchMode(true);
//设置常量
setKeepScreenOn(true);
}
public void surfaceCreated(SurfaceHolder holder) {
isRunning=true;
thread=new Thread(this);
thread.start(); }
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub }
public void surfaceDestroyed(SurfaceHolder holder) {
isRunning=false; }
public void run() {
//不断进行绘制
while (isRunning)
{
draw();
}
}
private void draw() {
try {
mCanvas=mHolder.lockCanvas();
if (mCanvas!=null) {
//
}
}
catch (Exception e) { }
finally
{
if (mCanvas!=null) {
mHolder.unlockCanvasAndPost(mCanvas);
}
}
} }
SurfaceViewTemplate
三、代码编写
- 绘制抽奖转盘的盘快
- 绘制背景: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。
private void drawBg() {
mCanvas.drawColor(0xFFFFFFFF);
mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding/2, mPadding/2, getMeasuredWidth()-mPadding/2, getMeasuredHeight()-mPadding/2), null);
}drawBg
- 绘制盘快:
//绘制盘快
float tmpAngle=mStartAngle;
float sweepAngle=360/mItemCount;
for (int i = 0; i < mItemCount; i++) {
mArcPaint.setColor(mColor[i]);
//绘制盘快
mCanvas.drawArc(mRange, tmpAngle, sweepAngle,true, mArcPaint);
- 绘制抽奖转盘的奖项文字
/**
* 绘制每个盘快的文本
* @param tmpAngle
* @param sweepAngle
* @param string
*/
private void drawText(float tmpAngle, float sweepAngle, String string) {
Path path=new Path();
path.addArc(mRange, tmpAngle, sweepAngle);
//利用水平偏移量让文字居中
float textWidth=mTextPaint.measureText(string);
int hOffset=(int) (mRadius*Math.PI/mItemCount/2-textWidth/2);
int vOffset=mRadius/2/6;//垂直偏移量
mCanvas.drawTextOnPath(string, path, hOffset, vOffset, mTextPaint);
}
drawText
- 绘制抽奖转盘的图片
/**
* 绘制图片
* @param tmpAngle
* @param bitmap
*/
private void drawIcon(float tmpAngle, Bitmap bitmap) {
//设置图片的宽度为直径的1/8
int imgWidth=mRadius/8;
float angle=(float) ((tmpAngle+360/mItemCount/2)*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(bitmap, null, rect,null);
}
drawIcon
- 转盘滚动及设置停止的指向
private void draw() {
try {
mCanvas=mHolder.lockCanvas();
if (mCanvas!=null) {
//绘制背景
drawBg();
//绘制盘快
float tmpAngle=mStartAngle;
float sweepAngle=360/mItemCount;
for (int i = 0; i < mItemCount; i++) {
mArcPaint.setColor(mColor[i]);
//绘制盘快
mCanvas.drawArc(mRange, tmpAngle, sweepAngle,true, mArcPaint);
//绘制文本
drawText(tmpAngle,sweepAngle,mStrings[i]);
//绘制图片
drawIcon(tmpAngle,mImagBitmaps[i]);
tmpAngle+=sweepAngle;
}
mStartAngle+=mSpeed;
//判断是否点击停止按钮
if (isShouldEnd) {
mSpeed-=1;
}
if (mSpeed<=0)
{
mSpeed=0;
isShouldEnd=false;
}
}
}
catch (Exception e) { }
finally
{
if (mCanvas!=null) {
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
draw
四、抽奖转盘的秘密
/**
* 电机启动旋转
* 控制指定盘快停止范围
* @param index
*/
public void luckyStart(int index)
{
//计算每一项的角度
float angle=360/mItemCount;
//计算每一项的中奖范围
//1->150~210
//0->210~270
float from=270-(index+1)*angle;
float end=from+angle;
// 设置停下来需要旋转的距离
float targetFrom=4*360+from;
float targetEnd=4*360+end;
/**
* <pre>
* v1->0 且每次-1
* (v1+0)*(v1+1)/2=targetFrom 等差数列求和公式;
* v1*v1+v1-2*targetFrom=0;
* v1=(-1+Math.sqrt(1+8*targetFrom))/2 一元二次方程求根公式
* </pre>
*/
float v1=(float) ((-1+Math.sqrt(1+8*targetFrom))/2);
float v2=(float) ((-1+Math.sqrt(1+8*targetEnd))/2);
mSpeed=v1+Math.random()*(v2-v1);
// mSpeed=v2;
isShouldEnd=false;
}
luckyStart
Android实现抽奖转盘的更多相关文章
- android仿漫画源码、抽奖转盘、Google相册、动画源码等
Android精选源码 android实现仿今日头条的开源项目 波浪效果,实现流量的动态显示 美妆领域的app, 集成了摄像头取色, 朋友圈, 滤镜等 android仿漫画源码 android一个视差 ...
- jquery实现抽奖转盘
用jquery通过配置参数实现抽奖转盘 1.html代码 <!DOCTYPE html> <html lang="zh-CN"> <head> ...
- JS:九宫格抽奖转盘实例
工作需要,所以做了个抽奖转盘的插件,当然这里只做最简单的演示.可以用于取代一些flash抽奖程序. 机制说明: 1.通过定义lottery-unit来控制节点的个数及索引: 2.通过设置lottery ...
- Html5-Canvas实现简易的抽奖转盘
###Html5实现抽奖转盘效果 1.实现的基本效果 2.主要的内容 html5中canvas标签的使用 jQueryRotate.js旋转插件 3.主要html代码 <body> < ...
- 使用CSS3+jquery.js 实现微信抽奖转盘效果
上次发表了一篇 微信抽奖转盘活动-效果源码分析 最近想起了刚接到这个项目时第一时间脑海里迸出的解决方法 “CSS3”! 为什么不能用CSS3来实现呢? 所以我打算用CSS3来实现这个效果.并不需要依赖 ...
- 抽奖转盘(jqueryrotate.js)
jqueryrotate.js抽奖转盘,使用方便,兼容各浏览器,效果如下图 <!DOCTYPE> <head> <meta http-equiv="Conten ...
- 利用java实现抽奖转盘(着重安全控制)
本文是针对jquery 实现抽奖转盘作者的一个补充(主要用java去实现转盘结果生成及存储,解决jquery 做法 非法用户采用模拟器实现改变转盘值的风险性),针对jQuery的具体实现,请看案例:h ...
- 用CSS实现一个抽奖转盘
效果 基本是用CSS实现的,没有用图片,加一丢丢JS.完全没有考虑兼容性. 首先画一个转盘, <!DOCTYPE html> <html lang="en"> ...
- css 如何“画”一个抽奖转盘
主要描述的是如何运用 css 绘制一个抽奖转盘,并运用原生 js 实现转盘抽奖效果. 先来张效果图: 布局 一般来说,转盘一般有四个部分组成:外层闪烁的灯.内层旋转的圆盘.圆盘上的中奖结果.指针. 所 ...
随机推荐
- On-board diagnostics -- Standards documents
http://en.wikipedia.org/wiki/On-board_diagnostics#Standards_documents SAE standards documents on OBD ...
- Java组各任务工作流程
1.周枫 A.提供基于SQL SERVER的数据库基本表结构创建脚本,基础数据脚本,按学科(产品)的数据脚本. 2.吴缤 A.提供给周茉的安装包用的项目文件,共三个digital,xylinkWeb和 ...
- char.js专门用来做数据统计图
<canvas id="cashback" width="930" height="460"></canvas>&l ...
- jquery控制css的display(控制元素的显示与隐藏)
使用jquery控制div的显示与隐藏: $("#div的id").show()表示display:block, $("#div的id").hide()表示di ...
- 《MySQL必知必会》读书笔记
一.了解MySQL 1.什么是数据库? 数据库是一种以某种有组织的方式存储的数据集合. 2.模式(schema):关于数据库和表的布局及特性的信息. 3. ...
- JavaEE系列之(二)commons-fileupload实现文件上传、下载
一.文件上传概述 实现Web开发中的文件上传功能,需要两步操作: 1.在Web页面中添加上传输入项 <form action="#" method=" ...
- java 验证码图片处理类,为验证码识别做准备
/* * To change this template, choose Tools | Templates * and open the template in the editor. */pack ...
- 判断浏览器是否IE10
项目中做打印预览时,在IE10中出现兼容性问题,需要针对IE10做特殊处理. 在网上搜了一下,有三种方法可以实现 一.特性检测:@cc_on <!--[if !IE]><!--> ...
- 0c-33-@class,循环retain
2个对象互相有着引用,A中有B,B中有A. // 对于循环retain的情况,对象不能够释放,此时只能让一方使用assign一方使用retain,retain用于对象assign用于基本类型,assi ...
- c#怎么把byte转化成int
三种方法来进行转换.(1) 在.NET Framework类库的System名字空间中有个叫做BitConverter的类,它是专门用来进行这种转换的.主要方法:1> GetBytes()方法 ...