android 水平进度条 文本动态 颜色渐变 达到指定值颜色动态变更

686 阅读1分钟

小于75

image.png

达到75以上渐变色修改

image.png

TestProgressBar.kt源码

class TextProgressBar : ProgressBar {
    var paint: Paint? = null//Paint()
    var paintBg: Paint? = null//Paint(Paint.ANTI_ALIAS_FLAG)
    var bounds: Rect? = null// Rect()
    var rect: RectF? = null//
    var mLinearGradient: LinearGradient? = null
    /* LinearGradient(
        0f,
        0f,
        getWidth().toFloat(),
        0f,
        intArrayOf(0xFFD8EDD9.toInt(), 0xFF4CAF50.toInt()), null, Shader.TileMode.CLAMP
    )*/

    constructor(context: Context?) : super(context) {
        paint = Paint()
        paintBg = Paint(Paint.ANTI_ALIAS_FLAG)
        bounds = Rect()
        LogUtils.d("宽度1${width},${height},${getWidth()}")
        rect = RectF(0f, 0f, width.toFloat(), height.toFloat()); // 矩形的坐标和尺寸
        mLinearGradient = LinearGradient(
            0f,
            0f,
            getWidth().toFloat(),
            0f,
            intArrayOf(0xFFD8EDD9.toInt(), 0xFF4CAF50.toInt()), null, Shader.TileMode.CLAMP
        )
    }

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
        paint = Paint()
        paintBg = Paint(Paint.ANTI_ALIAS_FLAG)
        bounds = Rect()
        LogUtils.d("宽度2${width},${height}")

    }

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        paint = Paint()
        paintBg = Paint(Paint.ANTI_ALIAS_FLAG)
        LogUtils.d("宽度3${width},${height}")
        bounds = Rect()
        rect = RectF(0f, 0f, width.toFloat(), height.toFloat()); // 矩形的坐标和尺寸

        mLinearGradient = LinearGradient(
            0f,
            0f,
            getWidth().toFloat(),
            0f,
            intArrayOf(0xFFD8EDD9.toInt(), 0xFF4CAF50.toInt()), null, Shader.TileMode.CLAMP
        )
    }

    var onProgressChangeCallbackListener: ((Int) -> Unit)? = null
    
    //超过的百分比,最大不能超过100%
    var maxProcessForChange = 90

    //达maxProcessForChange的进度值,是否要修改进度值的前置条颜色
    var changeProcessDrawable: Boolean = true

    //默认渐变颜色
    var newProcessDrawable: Drawable = ResUtils.getDrawable(R.drawable.pg_bg_bar)
    var defaultProgressDrawable: Drawable = ResUtils.getDrawable(R.drawable.item_bg_bar)

    @Synchronized
    public override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        LogUtils.d("宽度4,${width},${height},${getWidth().toFloat()}")

        // 获取当前进度
        val progress = progress
        // 将进度转换为字符串
        var text = progress.toString()
        // 获取ProgressBar的宽度和高度
        val width = width
        val height = height
        // 创建画笔对象,并设置颜色、字体大小等属性
        paint?.color = Color.BLACK
        paint?.textSize = 24f
        // 计算文本的宽度和高度
        paint?.getTextBounds(text, 0, text.length, bounds)
        val textWidth = bounds?.width()
        val textHeight = bounds?.height()
        // 计算文本的位置,并将其绘制到ProgressBar上
        val x = (width / 2 - (textWidth?.div(2) ?: 1)).toFloat()
        val y = (height / 2 + (textHeight?.div(2) ?: 1)).toFloat()
        val max = max
        if (max == 0) {
            text = "100"
        } else {
            text = (progress * 100 / max).toString()
        }
        if (text.toInt() >= maxProcessForChange) {
            setNewProgressDrawable(newProcessDrawable)
        } else {
            setNewProgressDrawable(defaultProgressDrawable)
        }
        paint?.let { canvas.drawText(text + "%", x, y, it) }
    }

    /**
     * 修改进度前置条的颜色
     */
    fun setNewProgressDrawable(drawable: Drawable?) {
        if (!changeProcessDrawable) return
        progressDrawable = drawable ?: newProcessDrawable
    }
}

@BindingAdapter(
    value = ["TextProgressBar_maxChangeColorValue", "TextProgressBar_progressDrawable", "TextProgressBar_newProgressDrawable"],
    requireAll = false
)
fun TextProgressBar_changed(
    view: TextProgressBar,
    maxChangeByColor: Int?,
    drawable: Drawable?,
    newDrawable: Drawable?
) {
    if (maxChangeByColor != null) {
        view.maxProcessForChange = maxChangeByColor
    }

    if (newDrawable != null) {
        view.newProcessDrawable = newDrawable
    }
    if (drawable != null) view.defaultProgressDrawable = drawable

}

xml引用


<com.example.lanidemokt.widget.TextProgressBar
        android:id="@+id/tpbar"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/pgbar2"
        android:background="@drawable/item_bg_bar"
        android:progressDrawable="@drawable/my_progress_bar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="16dp"
        android:layout_marginTop="18dp"
        android:progress="@{vm.barPercent}"
        TextProgressBar_maxChangeColorValue="@{75}"
        TextProgressBar_newProgressDrawable="@{vm.newDrawable}"
        TextProgressBar_progressDrawable="@{@drawable/my_progress_bar}"
        android:layout_marginHorizontal="20dp"
        android:max="100" />
<color name="progress_bg_color">#E4E4E4</color>

背景色item_bg_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/progress_bg_color" />
    <corners android:radius="15dp" />
</shape>

渐变色my_progress_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="35dp" />
        </shape>
        <color android:color="#999" />
    </item>

    <item android:id="@android:id/progress">
        <clip
                android:clipOrientation="horizontal"
                android:gravity="left">
            <shape>
                <corners android:radius="15dp" />
                <!--   android:centerColor="#FFFF00"-->
                <gradient
                        android:startColor="#83ADF4"
                        android:endColor="#2574FF" />
            </shape>
        </clip>
    </item>
</layer-list>