安卓原生抽奖转盘

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值