import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
/**
*created by 淹死的鱼 on 2019/12/11
*/
class ProgressBar @JvmOverloads constructor(
context: Context,
attSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attSet, defStyleAttr) {
private var proTextColor = 0
private var selectColor = 0
private var unSelectColor = 0
private var borderWidth = 3f
private var proTextSize = 15
private var orientation = 1
private var maxProgress = 100
private var currentProgress = 0
//外圈画笔
private val unSelectPaint: Paint
//内圈画笔
private val selectPaint: Paint
private val textPaint: Paint
var text = ""
init {
val typedArray = context.obtainStyledAttributes(attSet, R.styleable.ProgressBar)
proTextColor = typedArray.getColor(R.styleable.ProgressBar_proTextColor, proTextColor)
selectColor = typedArray.getColor(R.styleable.ProgressBar_proInnerColor, selectColor)
unSelectColor = typedArray.getColor(R.styleable.ProgressBar_proOutColor, unSelectColor)
borderWidth = typedArray.getDimension(R.styleable.ProgressBar_proBorderWidth, dip2px(borderWidth.toInt()))
proTextSize = typedArray.getDimensionPixelSize(R.styleable.ProgressBar_proTextSize, sp2px(proTextSize.toFloat()))
orientation = typedArray.getInt(R.styleable.ProgressBar_proOrientation, orientation)
maxProgress = typedArray.getInt(R.styleable.ProgressBar_maxProgress, maxProgress)
typedArray.recycle()
unSelectPaint = getPaint(unSelectColor)
selectPaint = getPaint(selectColor)
textPaint = Paint()
textPaint.color = proTextColor
textPaint.isAntiAlias = true
textPaint.textSize = proTextSize.toFloat()
}
private fun getPaint(color: Int) = Paint().apply {
this.color = color
this.isAntiAlias = true
this.isDither = true
strokeWidth = borderWidth
style = Paint.Style.STROKE
}
private fun sp2px(sp: Float): Int {//不建议用这样的方式转单位
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, resources.displayMetrics).toInt()
}
private fun dip2px(dip: Int): Float {//不建议用这样的方式转单位
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip.toFloat(), resources.displayMetrics)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
if (orientation == 2) {
setMeasuredDimension(if (width > height) height else width, if (width > height) height else width)
} else {
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
if (borderWidth <= 0) {
setMeasuredDimension(width, dip2px(20).toInt())
} else {
setMeasuredDimension(width, borderWidth.toInt())
}
} else {
unSelectPaint.strokeWidth = height.toFloat()
selectPaint.strokeWidth = height.toFloat()
setMeasuredDimension(width, height)
}
}
val center = width / 2f
val radius = width / 2 - borderWidth / 2
rectF.set(center - radius, center - radius, center + radius, center + radius)
}
private val rect = Rect()
private var rectF = RectF()
override fun onDraw(canvas: Canvas) {
textPaint.getTextBounds(text, 0, text.length, rect)
val metricsInt = textPaint.fontMetricsInt
val dy = (metricsInt.bottom - metricsInt.top) / 2 - metricsInt.bottom
val baseLine = height / 2f + dy
//1画圆
if (orientation == 2) {
//画外圆
canvas.drawCircle(width / 2f, height / 2f, width / 2 - borderWidth / 2, unSelectPaint)
//画进度
canvas.drawArc(rectF, 90f, (currentProgress.toFloat() / maxProgress) * 360, false, selectPaint)
//画文字
canvas.drawText(text, width / 2 - rect.width() / 2f, baseLine, textPaint)
} else {
val y = height / 2f
//画总长渡
canvas.drawLine(0f, y, width.toFloat(), y, unSelectPaint)
//画进度
canvas.drawLine(0f, y, (currentProgress.toFloat() / maxProgress) * width, y, selectPaint)
//画文字
canvas.drawText(text, width / 2 - rect.width() / 2f, baseLine, textPaint)
}
}
@Synchronized
fun setMaxProgress(max: Int) {
maxProgress = max
}
@Synchronized
fun setProgress(current: Int) {
if (current < 0 || current > maxProgress) return
currentProgress = current
invalidate()
}
}
<declare-styleable name="ProgressBar">
<attr name="proBorderWidth" format="dimension" />
<attr name="proInnerColor" format="color" />
<attr name="proOutColor" format="color" />
<attr name="proTextColor" format="color" />
<attr name="proTextSize" format="dimension" />
<attr name="proOrientation" format="enum">
<enum name="proHorizontal" value="1" />
<enum name="proCircle" value="2" />
</attr>
<attr name="maxProgress" format="integer" />
</declare-styleable>
网友评论