公司要做一个签到抽奖的功能,本来想用H5写的,但是可能会加载有点慢,最主要的是JS写的canvas绘制渲染感觉不是很好,改成原生的吧,后期还可再优化
先来张效果图:
实现功能:
1、自定义奖品个数
2、可控制抽中的选项
定义了一个MyCanvas类,来实现转盘功能
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* Created by GLX on 2016/12/17.
*/
public class MyCanvas extends View implements Runnable {
private List<String> jiangpinList = new ArrayList<>();
/**
* 平分的个数
*/
private int num;
/**
* 圆环是否绘制完毕
*/
private boolean isOK = false;
private Context context;
public MyCanvas(Context context) {
super(context);
init(context);
}
public MyCanvas(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyCanvas(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
private Paint p1;
private Paint p2;
private Paint ptex;
private Canvas Mycanvas;
/**
* 是否开始旋转
*/
private boolean isStart = false;
private Thread thread;
/**
* 每次绘制间隔时间
*/
private int stopTime = 40;
/**
* 画布需要旋转的角度
*/
private int jiaodu = 0;
/**
* 画布每旋转一次增加的角度
*/
private int everyJiaodu = 15;
private int everyAddJiaodu = everyJiaodu;
private Matrix matrix;
private Handler mHandler;
private void init(Context context) {
this.context = context;
newThread();
this.mHandler = new Handler(context.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//抽奖完成回调接口
wanCheng.isOK();
}
};
p1 = new Paint();
p2 = new Paint();
ptex = new Paint();
p1.setColor(0xFFFFF4D6);// 鹅黄
p2.setColor(Color.WHITE);// 设置白色
ptex.setColor(0xFFE62D2D);
ptex.setTextSize(20);
ptex.setTextAlign(Paint.Align.CENTER);
p1.setAntiAlias(true);
p2.setAntiAlias(true);
ptex.setAntiAlias(true);
matrix = new Matrix();
String[] tt = {"0.1元", "1.8元", "0.3元", "3.6元", "0.5元", "5元", "0.8元", "再接再厉"};
for (int i = 0; i < tt.length; i++) {
jiangpinList.add(tt[i]);
}
num = jiangpinList.size();
JiSuan();
}
private float DanJiaoDu;
private List<YuanHuClass> yuanHuClassList = new ArrayList<>();
boolean isshuang = true;
private void JiSuan() {
DanJiaoDu = (float) 360 / (float) num;
yuanHuClassList.clear();
for (int i = 0; i < num; i++) {
float startJiaodu = (float) i * DanJiaoDu;
float stopJiaodu = (float) (i + 1) * DanJiaoDu;
yuanHuClassList.add(new YuanHuClass(jiangpinList.get(i), startJiaodu, stopJiaodu, 90 + startJiaodu + DanJiaoDu / (float) 2));
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (Mycanvas == null) {
Mycanvas = canvas;
}
// canvas.drawColor(0x00E62D2D);
// 画弧,第一个参数是RectF:该类是第二个参数是角度的开始,第三个参数是多少度,第四个参数是真的时候画扇形,是假的时候画弧线
for (int i = 0; i < num; i++) {
YuanHuClass yuanHuClass = yuanHuClassList.get(i);
float Viewstart = yuanHuClass.getStartJiaoDu();
float Viewstop = yuanHuClass.getStopJiaoDu();
RectF oval2 = new RectF(0, 0, getWidth(), getHeight());// 设置个新的长方形,扫描测量
//绘制扇形
if (isshuang) {
canvas.drawArc(oval2, Viewstart, DanJiaoDu, true, p1);
} else {
canvas.drawArc(oval2, Viewstart, DanJiaoDu, true, p2);
}
isshuang = !isshuang;
canvas.save();
float texJiaoDu = 90 + Viewstart + DanJiaoDu / 2;
canvas.rotate(texJiaoDu, getWidth() / 2, getHeight() / 2);
//绘制文字
canvas.drawText(yuanHuClass.getTitle(), getWidth() / 2, 50, ptex);
canvas.restore();
if (isStart) {
yuanHuClass.setStartJiaoDu((Viewstart + everyAddJiaodu) % 360);
yuanHuClass.setStopJiaoDu((Viewstop + everyAddJiaodu) % 360);
}
}
if (isStart) {
canvas.rotate(jiaodu, getWidth() / 2, getHeight() / 2);
}
}
@Override
public void run() {
while (isStart) {
JianSu();
long startTime = System.currentTimeMillis();
jiaodu += everyAddJiaodu;
if (jiaodu % 360 == 0) {
jiaodu = 0;
}
doActionHandler.sendMessage(new Message());
long endTime = System.currentTimeMillis();
if (endTime - startTime < stopTime) {
try {
Thread.sleep(stopTime - endTime + startTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 已经经过的时间
*/
private int allTime = 0;
private int nnn = 0;
/**
* 旋转减速
*/
private void JianSu() {
allTime += everyAddJiaodu;
if (allTime > 500) {
if (everyAddJiaodu == 1) {
if (StopJiaoDu + 1 >= jiaodu % 360 && StopJiaoDu - 1 <= jiaodu % 360) {
everyAddJiaodu = 0;
}
}
if (nnn % 30 == 0 && everyAddJiaodu > 1) {
if (everyAddJiaodu <= 4 && jiaodu + 16 >= StopJiaoDu) {
if (everyAddJiaodu != 1) {
everyAddJiaodu -= 1;
}
} else {
everyAddJiaodu -= 2;
}
if (everyAddJiaodu < 0) {
everyAddJiaodu = 1;
}
nnn = 0;
}
nnn++;
if (everyAddJiaodu <= 0) {
setStop();
}
}
}
private Handler doActionHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
invalidate();
}
};
/**
* 停止时的角度
*/
private float StopJiaoDu = 0;
/**
* 设置停止的选项
*
* @param item
*/
public void setItem(int item) {
if (item > jiangpinList.size()) {
return;
}
JiSuan();
StopJiaoDu = (8 - item) * DanJiaoDu + DanJiaoDu / 2 - 90;
if (StopJiaoDu < 0) {
StopJiaoDu = 360 + StopJiaoDu;
}
setStart();
}
/**
* 停止旋转回调接口
*/
public interface WanCheng {
void isOK();
}
WanCheng wanCheng = null;
public void setOK(WanCheng wanCheng) {
this.wanCheng = wanCheng;
}
/**
* 停止旋转
*/
public void setStop() {
isStart = false;
thread = null;
everyAddJiaodu = everyJiaodu;
nnn = 0;
Message message = new Message();
message.what = 123;
mHandler.sendMessage(message);
}
public void isStop(){
isStart = false;
thread = null;
everyAddJiaodu = everyJiaodu;
nnn = 0;
}
/**
* 开始旋转
*/
public void setStart() {
if (isStart) {
return;
}
if (thread == null) {
newThread();
}
isStart = true;
thread.start();
}
private void newThread() {
thread = new Thread(this);
}
}
原理就是canvas的重绘,代码还算清楚,就不多说啦