公司要做一個簽到抽獎的功能,本來想用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的重繪,代碼還算清楚,就不多說啦
新聞熱點
疑難解答