为了买彩票,我写了这个控件

作者 : 开心源码 本文共5001个字,预计阅读时间需要13分钟 发布时间: 2022-05-12 共210人阅读

0.

最近偶尔会买个双色球,一周买个6块钱的,也不多,就是凑个热闹,为生活增加个小情趣。由于不会选号,每次都是机选,作为一个阴谋论者,我觉得机选可能不够“随机”,为此我决定自己写个程序为我选号,为此我模仿老虎机写了一个控件。先上图

image

1.

先设计一下

1.1支持从数字和数组获取数据

1.2绘制两个数字,当前数字和下一个数字

1.3设置便宜量,并实现加速

1.4开始和中止,中止时增加回调

1.5支持设置文字大小与颜色

2.

废话少说,上代码

package com.skateboard.numberrunningviewimport android.content.Contextimport android.graphics.Canvasimport android.graphics.Colorimport android.graphics.Paintimport android.support.v4.view.ViewCompatimport android.util.AttributeSetimport android.view.Viewclass NumberRunningView(context: Context, attributes: AttributeSet?) : View(context, attributes) {    private var numberColor = Color.WHITE    private var numberSize = 15.0f        //开始时的数字或者者数组下标    var min = 0   //最大的数字或者者数组下标    var max = 0   //当前要绘制数字或者者数组下标    private var now = min   //每次刷新移动的距离    private var offset = 0    private var paint = Paint(Paint.ANTI_ALIAS_FLAG)    private var isStart = false    var maxSpeed = 10f    //当前移动速度    private var curSpeed = 0f    //加速度增量    private var speedOffset = 0.1f    var dataList: List<Int>? = null        set(value) {            field = value            min = 0            max = (value?.size ?: 1) - 1            now = min            offset = 0        }    var onNumberSelectedListener: OnNumberSelectedListenern? = null    init {        if (attributes != null) {            parseAttrs(attributes)        }        initPaint()    }    constructor(context: Context) : this(context, null)    private fun parseAttrs(attributes: AttributeSet) {        val typedArray = context.obtainStyledAttributes(attributes, R.styleable.NumberRunningView)        min = typedArray.getInt(R.styleable.NumberRunningView_min, min)        max = typedArray.getInt(R.styleable.NumberRunningView_max, max)        maxSpeed = typedArray.getFloat(R.styleable.NumberRunningView_maxSpeed, maxSpeed)        numberColor = typedArray.getColor(R.styleable.NumberRunningView_numberColor, numberColor)        numberSize = typedArray.getDimension(R.styleable.NumberRunningView_numberSize, numberSize)        speedOffset = typedArray.getFloat(R.styleable.NumberRunningView_speedOffset, 0.1f)        typedArray.recycle()        now = min    }    private fun initPaint() {        paint.textSize = numberSize        paint.color = numberColor    }    override fun onDraw(canvas: Canvas?) {        super.onDraw(canvas)        canvas?.let {            drawNow(it)            drawNext(it)            calCurSpeed()            calOffset()        }    }    private fun calCurSpeed() {        curSpeed += speedOffset        if (curSpeed > maxSpeed) curSpeed = maxSpeed    }    private fun drawNow(canvas: Canvas) {        val curDataList = dataList        var nowNum = "0"        nowNum = if (curDataList != null) {            curDataList[now].toString()        } else {            now.toString()        }        val numWidth = paint.measureText(nowNum)        canvas.drawText(nowNum, width / 2 - numWidth / 2, height / 2 - offset + paint.textSize / 2, paint)    }    private fun drawNext(canvas: Canvas) {        val curDataList = dataList        var nextNum = ""        if (curDataList == null) {            nextNum = if (now + 1 > max) {                min.toString()            } else {                (now + 1).toString()            }        } else {            nextNum = if (now + 1 > max) {                curDataList[min].toString()            } else {                (curDataList[now + 1]).toString()            }        }        val numWidth = paint.measureText(nextNum)        canvas.drawText(nextNum, width / 2 - numWidth / 2, 1.5f * height - offset + paint.textSize / 2, paint)    }    private fun calOffset() {        if (isStart) {            if (offset == height) {                offset = 0                if (now + 1 > max) {                    now = min                } else {                    now += 1                }            } else if (offset + curSpeed > height) {                offset = height            } else {                offset = (offset + curSpeed).toInt()            }            postInvalidate()        } else {            if (offset != 0 && offset != height) {                offset = if (offset + curSpeed > height) {                    height                } else {                    (offset + curSpeed).toInt()                }                postInvalidate()            } else {                if (offset == 0) {                    val curDataList = dataList                    if (curDataList != null) {                        onNumberSelectedListener?.onNumberSelected(curDataList[now])                    } else {                        onNumberSelectedListener?.onNumberSelected(now)                    }                } else {                    val curDataList = dataList                    if (curDataList != null) {                        onNumberSelectedListener?.onNumberSelected(if (now == max) curDataList[min] else curDataList[now + 1])                    } else {                        onNumberSelectedListener?.onNumberSelected(if (now == max) min else now + 1)                    }                }            }        }    }    fun start() {        if (isStart) {            return        }        curSpeed = 0f        isStart = true        if (ViewCompat.isAttachedToWindow(this)) {            postInvalidate()        }    }    fun stop() {        isStart = false    }       interface OnNumberSelectedListenern {        fun onNumberSelected(num: Int)    }}

代码比较简单,没什么难度,先看onDraw方法

 override fun onDraw(canvas: Canvas?) {        super.onDraw(canvas)        canvas?.let {            drawNow(it)            drawNext(it)            calCurSpeed()            calOffset()        }    }

绘制当前数字,绘制下一个数字,计算当前速度,计算偏移量,这个速度主要是用来看起来开始时数字的翻转有一个加速的过程。看一下drawNow方法

 private fun drawNow(canvas: Canvas) {        val curDataList = dataList        var nowNum = "0"        nowNum = if (curDataList != null) {            curDataList[now].toString()        } else {            now.toString()        }        val numWidth = paint.measureText(nowNum)        canvas.drawText(nowNum, width / 2 - numWidth / 2, height / 2 - offset + paint.textSize / 2, paint)    }

首先根据数据源的不同获取的数据,而后计算文字绘制的位置,而后绘制
drawNext大同小异,无非就是一个下一个数字的判断问题
calOffset方法

 private fun calOffset() {        if (isStart) {            if (offset == height) {                offset = 0                if (now + 1 > max) {                    now = min                } else {                    now += 1                }            } else if (offset + curSpeed > height) {                offset = height            } else {                offset = (offset + curSpeed).toInt()            }            postInvalidate()        } else {            if (offset != 0 && offset != height) {                offset = if (offset + curSpeed > height) {                    height                } else {                    (offset + curSpeed).toInt()                }                postInvalidate()            } else {                if (offset == 0) {                    val curDataList = dataList                    if (curDataList != null) {                        onNumberSelectedListener?.onNumberSelected(curDataList[now])                    } else {                        onNumberSelectedListener?.onNumberSelected(now)                    }                } else {                    val curDataList = dataList                    if (curDataList != null) {                        onNumberSelectedListener?.onNumberSelected(if (now == max) curDataList[min] else curDataList[now + 1])                    } else {                        onNumberSelectedListener?.onNumberSelected(if (now == max) min else now + 1)                    }                }            }        }    }

假如处于运行状态,先判断控件当前偏移量,假如等于控件高度,那么就重置为0,而后将now置为下一个数,否则就加上速度重新计算偏移量。假如不处于运行状态,那么判断当前的偏移量,假如既不等于0也不等于控件高度,说明处于一个中间状态,那么就让它移到下一个位置,并调用回调函数。其余的也没什么关键了,各位有需要的看代码就好了

3.

github

image

关注我的公众号

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 为了买彩票,我写了这个控件

发表回复