一个简单的圆角进度条

2020-03-07  本文已影响0人  祥龙翔天

一个简单圆角进度条

突然闲下来,就的写了一个,效果图如下

简单圆角进度条.gif

xml局部代码如下:

<TextView
    android:id="@+id/id_txv_01"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="随进度变色"
    android:layout_marginTop="50dp"
    android:layout_marginStart="20dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/id_txv_02"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="不变色"
    android:layout_marginTop="30dp"
    app:layout_constraintEnd_toEndOf="@id/id_txv_01"
    app:layout_constraintTop_toBottomOf="@id/id_txv_01" />

<com.example.myapplication.ui.custom.MainPageProgressBar
    android:id="@+id/id_pgs_main"
    android:layout_width="400dp"
    android:layout_height="20dp"
    android:layout_marginStart="10dp"
    app:layout_constraintBottom_toBottomOf="@id/id_txv_01"
    app:layout_constraintStart_toEndOf="@id/id_txv_01"
    app:layout_constraintTop_toTopOf="@id/id_txv_01" />

<com.example.myapplication.ui.custom.BaseProgressBar
    android:id="@+id/id_pgs_base"
    android:layout_width="400dp"
    android:layout_height="20dp"
    android:layout_marginStart="10dp"
    app:layout_constraintBottom_toBottomOf="@id/id_txv_02"
    app:layout_constraintStart_toEndOf="@id/id_txv_02"
    app:layout_constraintTop_toTopOf="@id/id_txv_02" />

Activity局部代码如下:

val pgsBase = activity?.findViewById<BaseProgressBar>(R.id.id_pgs_base)
val pgsMain = activity?.findViewById<MainPageProgressBar>(R.id.id_pgs_main)
var count = 0
Thread(Runnable {
    Thread.sleep(2000)
    var flag = true
    while (flag) {
        count += 1
        Thread.sleep(100)
        pgsBase?.setProgress(count * 10 % 1001)
        pgsMain?.setProgress(count * 10 % 1001)
        if (count > 99) {
            flag = false
        }
    }
}).start()

控件基本版代码如下:

package com.example.myapplication.ui.custom

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import kotlin.math.min

open class BaseProgressBar : View {

    private var rectFBackground = RectF()
    private var rectFProgress = RectF()
    private var paintBackground = Paint()
    private var paintPg = Paint()
    private var path = Path()
    private var colorBackground = Color.GRAY
    private var colorPg = Color.GREEN
    private var progress = 0
    private var cornerWidth = 0f
    private var maxWidth = 1000f

    constructor(context: Context) : super(context) {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init(context)
    }

    private fun init(context: Context) {

        paintBackground.style = Paint.Style.FILL
        paintBackground.isAntiAlias = true
        paintBackground.color = colorBackground

        paintPg.style = Paint.Style.FILL
        paintPg.isAntiAlias = true
        paintPg.color = colorPg

    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        if (paintBackground.color != colorBackground) {
            paintBackground.color = colorBackground
        }

        if (paintPg.color != colorPg) {
            paintPg.color = colorPg
        }

        // 画背景
        canvas.drawRoundRect(rectFBackground, cornerWidth, cornerWidth, paintBackground)

        canvas.save()

        // clip一个和background一样的区域
        // 使得progress移动的时候(特别是在百分比很小的时候)显示正常
        path.addRoundRect(rectFBackground, cornerWidth, cornerWidth, Path.Direction.CW)
        canvas.clipPath(path)

        // 画progress
        val w = (rectFBackground.right - rectFBackground.left) * progress / maxWidth
        rectFProgress.set(rectFBackground)
        rectFProgress.right = w + rectFBackground.left
        canvas.drawRoundRect(rectFProgress, cornerWidth, cornerWidth, paintPg)

        canvas.restore()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        rectFBackground.left = paddingLeft.toFloat()
        rectFBackground.top = paddingTop.toFloat()
        rectFBackground.right = (w - paddingRight).toFloat()
        rectFBackground.bottom = (h - paddingTop).toFloat()
        cornerWidth = min(w, h).toFloat() / 2
    }

    open fun setProgress(progress: Int) {
        this.progress = progress
        postInvalidate()
    }

    open fun setBgColor(color: Int) {
        colorBackground = color
    }

    open fun setPgColor(color: Int) {
        colorPg = color
    }

    fun setCornerWidth(width : Float) {
        cornerWidth = width
    }

    fun setMaxWidth(width: Float) {
        maxWidth = width
    }

    fun getMaxWidth(): Float {
        return maxWidth
    }
}

控件增强版如下:

package com.example.myapplication.ui.custom

import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import kotlin.math.roundToInt

class MainPageProgressBar : BaseProgressBar {
    constructor(context: Context) : super(context) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
    }

    override fun setProgress(progress: Int) {
        val percentInt = (progress * 100 / getMaxWidth()).toInt()
        val color = getColor(percentInt)
        setPgColor(color)
        super.setProgress(progress)
    }

    /**
     * 颜色渐变,由蓝色到绿色到黄色
     * 0到80,由蓝色到绿色
     * 80到100,有绿色到黄色
     * @param val
     * @return
     */
    private fun getColor(value: Int): Int {

        var r = 255
        var g = 255
        var b = 0

        val tmp = value / 100.0f * 255

        if (tmp >= 0 && tmp < 204) {// 0到80
            r = 0
            g = 255
            b = (255 - 255 / 204 * tmp).toInt()
        } else if (tmp >= 204 && tmp < 256) {// 80到100
            r = (5 * tmp - 1020).roundToInt()// 即y = 5x + b
            g = 255
            b = 0
        }
        return Color.rgb(r, g, b)
    }

}
上一篇下一篇

猜你喜欢

热点阅读