爲了買彩票,我寫了這個控件android
最近偶爾會買個雙色球,一週買個6塊錢的,也很少,就是湊個熱鬧,爲生活添加個小情趣程序員
由於不會選號,每次都是機選,做爲一個陰謀論者,我以爲機選可能不夠"隨機",爲此我決定本身寫個程序爲我選號,學過Java會Android的我模仿老虎機寫了一個控件。先上圖canvas
先設計一下數組
1.1支持從數字和數組獲取數據ide
1.2繪製兩個數字,當前數字和下一個數字函數
1.3設置便宜量,並實現加速post
1.4開始和中止,中止時添加回調this
1.5支持設置文字大小與顏色設計
廢話少說,上代碼3d
package com.skateboard.numberrunningview import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.support.v4.view.ViewCompat import android.util.AttributeSet import android.view.View class 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方法
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) } } } } }
控件代碼就所有告訴你們了,感覺一把隨機的樂趣,至於彩票,這是薛定諤的彩票。也不要太沉迷,要否則,最後就是西湖的水,個人淚。
喜歡這篇文章的朋友能夠關注我