CircleRingView.kt
package com.koolearn.android.view
import android.animation.ObjectAnimator
import com.koolearn.android.R
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
class CircleRingView(context: Context,attrs: AttributeSet) : View(context,attrs),ICircleRingView {
override fun setPercent(percent: Int) {
this.percent = percent
invalidate()
}
private var percent:Int=0
private val attr = RingViewAttr(context,attrs)
private val circlePaint = Paint()
private val ringPaint:Paint = Paint()
private val rectF = RectF(attr.ringWidth.toFloat()/2,attr.ringWidth.toFloat()/2,attr.ringDiameter.toFloat()-attr.ringWidth/2, attr.ringDiameter.toFloat()-attr.ringWidth/2)
var objectAnimator: ObjectAnimator?=null
init {
//初始化圓圈畫筆
circlePaint.color = attr.ringBgColor
circlePaint.isAntiAlias = true
circlePaint.style = Paint.Style.STROKE
circlePaint.strokeWidth = attr.ringWidth.toFloat()
//初始化圓環畫筆
ringPaint.color = attr.ringColor
ringPaint.isAntiAlias = true
ringPaint.style = Paint.Style.STROKE
ringPaint.strokeWidth = attr.ringWidth.toFloat()
ringPaint.strokeCap = Paint.Cap.ROUND
}
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.drawCircle(attr.ringDiameter.toFloat()/2, attr.ringDiameter.toFloat()/2,attr.ringDiameter.toFloat()/2-attr.ringWidth/2,circlePaint)
// ringPaint.shader = LinearGradient(attr.ringWidth.toFloat()/2,attr.ringWidth.toFloat()/2,attr.ringDiameter.toFloat()-attr.ringWidth/2, attr.ringDiameter.toFloat()-attr.ringWidth/2,Color.parseColor("#FF0000"),Color.parseColor("#0000FF"),Shader.TileMode.CLAMP)
canvas?.drawArc(rectF, -90f, 3.6f*percent, false, ringPaint)
ColorFilter()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(resolveSize(attr.ringDiameter,widthMeasureSpec), resolveSize(attr.ringDiameter,heightMeasureSpec))
}
/**
* 設置動畫移動的度數,取值0-100
*/
fun startAnim(progress:Int){
if(attr.isShowAnim){
objectAnimator = ObjectAnimator.ofInt(this,"percent",progress)
objectAnimator?.duration = progress*1000/attr.speed.toLong()
objectAnimator?.start()
}else{
setPercent(progress)
}
}
}
class RingViewAttr(context:Context,attrs:AttributeSet){
val ringColor: Int //圓環顏色
val ringBgColor:Int//圓環背景色
val ringDiameter:Int//圓環直徑
val ringWidth:Int//圓環粗細
val isShowAnim:Boolean//是否顯示動畫
val speed:Int//顯示動畫時長
init {
val ta = context.obtainStyledAttributes(attrs, R.styleable.CircleRingView)
ringColor = ta.getColor(R.styleable.CircleRingView_ringColor,Color.RED)
ringBgColor = ta.getColor(R.styleable.CircleRingView_ringBgColor, Color.WHITE)
ringDiameter = ta.getDimensionPixelSize(R.styleable.CircleRingView_ringDiameter, 40)
ringWidth = ta.getDimensionPixelSize(R.styleable.CircleRingView_ringWidth, 10)
isShowAnim = ta.getBoolean(R.styleable.CircleRingView_isShowAnim,false)
speed = ta.getInt(R.styleable.CircleRingView_speed, 100)
ta.recycle()
}
}
interface ICircleRingView{
fun setPercent(percent:Int)
}
複製代碼
命名空間
<declare-styleable name="CircleRingView">
<attr name="ringColor" format="color"/>
<attr name="ringBgColor" format="color"/>
<attr name="ringDiameter" format="dimension"/>
<attr name="ringWidth" format="dimension"/>
<attr name="isShowAnim" format="boolean"/>
<attr name="speed" format="integer"/>
</declare-styleable>
複製代碼