puzhibing
2026-08-21 5fa94b3718b4a78a4fcea4c97652b0ef20b7de3a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.xw.common.custom
 
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import android.view.animation.DecelerateInterpolator
import com.xw.common.R
import com.xw.common.utils.BindUtils.getResColor
 
// HorizontalProgressView.kt - 水平带动画进度条
class HorizontalProgressView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
 
    private var progress = 0f
    private var animatedProgress = 0f
    private val animator = ValueAnimator.ofFloat()
 
    private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG)
 
    private val cornerRadius = 20f
 
    init {
        backgroundPaint.color = getResColor(R.color.gray_6)
        progressPaint.color = getResColor(R.color.blue_5)
        textPaint.apply {
            color = Color.WHITE
            textSize = 28f
            textAlign = Paint.Align.CENTER
        }
 
        animator.apply {
            duration = 300
            interpolator = DecelerateInterpolator()
            addUpdateListener {
                animatedProgress = it.animatedValue as Float
                invalidate()
            }
        }
    }
 
    fun setProgress(value: Float, animate: Boolean = true) {
        progress = value.coerceIn(0f, 100f)
        if (animate) {
            animator.setFloatValues(animatedProgress, progress)
            animator.start()
        } else {
            animatedProgress = progress
            invalidate()
        }
    }
 
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
 
        // 背景
        val rect = RectF(0f, 0f, width.toFloat(), height.toFloat())
        canvas.drawRoundRect(rect, cornerRadius, cornerRadius, backgroundPaint)
 
        // 进度
        val progressWidth = (animatedProgress / 100f) * width
        if (progressWidth > 0) {
            val progressRect = RectF(0f, 0f, progressWidth, height.toFloat())
            canvas.drawRoundRect(progressRect, cornerRadius, cornerRadius, progressPaint)
 
            // 进度文字
            val text = "${animatedProgress.toInt()}%"
            val x = progressWidth / 2
            val y = height / 2f - (textPaint.descent() + textPaint.ascent()) / 2
            canvas.drawText(text, x, y, textPaint)
        }
    }
}