效果
圆形渐变色进度条源码
class CircleProgress @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val mPaint: Paint = Paint()
private val mRectF = RectF()
private val mRect = Rect()
val mTextPaint: Paint = Paint()
init {
mPaint.isAntiAlias = true
mPaint.style = Paint.Style.STROKE
mTextPaint.isAntiAlias = true
mTextPaint.strokeWidth = 0f
mTextPaint.textSize = 50f
mTextPaint.color = Color.WHITE
mTextPaint.isFakeBoldText = true
}
var textShow = false
var textCallback: ((Int) -> String) = { "${it}%" }
var circleSolidColor = Color.parseColor("#373737")
var arcWidth = 15f //圆弧(也可以说是圆环)的宽度
var maxValue = 100//最大值
var progressValue = 0
set(value) {
if (field == value) {
return
}
field = value
invalidate()
}
var mCircleShader: Shader? = null
private val mDefaultShader by lazy {
LinearGradient(
width.toFloat(), 0f, 0f, height.toFloat(), intArrayOf(
Color.parseColor("#FFCEFFEB"),
Color.parseColor("#FF9DA9FF"),
Color.parseColor("#FF9DA9FF"),
Color.parseColor("#FFE9B5FF")
), floatArrayOf(0f, 0.4f, 0.7f, 1f), Shader.TileMode.CLAMP
)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
//绘制圆形
//设置圆弧的宽度(圆环的宽度)
mPaint.shader = null
mPaint.style = Paint.Style.STROKE
mPaint.strokeWidth = arcWidth
mPaint.color = circleSolidColor
//大圆的半径
val bigCircleRadius = width.toFloat() / 2
//小圆的半径
val smallCircleRadius = bigCircleRadius - arcWidth
//绘制小圆
canvas.drawCircle(bigCircleRadius, bigCircleRadius, smallCircleRadius, mPaint)
mPaint.shader = mCircleShader ?: mDefaultShader
if (progressValue != 100) mPaint.strokeCap = Paint.Cap.ROUND
mRectF.set(arcWidth, arcWidth, width - arcWidth, width - arcWidth)
//绘制圆弧
canvas.drawArc(mRectF, 270f, (progressValue * 362 / maxValue).toFloat(), false, mPaint)
if (textShow) {
val txt = textCallback.invoke(progressValue * 100 / maxValue)
mTextPaint.getTextBounds(txt, 0, txt.length, mRect)
canvas.drawText(
txt,
bigCircleRadius - mRect.width() / 2,
bigCircleRadius + mRect.height() / 2,
mTextPaint
)
}
}
}
使用示例
binding.cps.textShow = true
val va = ValueAnimator.ofInt(0, 100)
va.addUpdateListener {
binding.cps.progressValue = it.animatedValue as Int
}
va.duration = 5000
va.startDelay = 1000
va.repeatCount = -1
va.repeatMode = ValueAnimator.RESTART
va.start()
如果本文对你有帮助就点个赞支持下吧~~~
网友评论