公司要做一个签到抽奖的功能,本来想用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的重绘,代码还算清楚,就不多说啦
新闻热点
疑难解答