一个简单圆角进度条
突然闲下来,就的写了一个,效果图如下

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)
}
}
网友评论