源码
自定义属性
<?xml version="1.0" encoding="utf-8"?>
< resources> < declare-styleable name = " ArcProgressView" > < attr name = " android:textSize" /> < attr name = " bgBorderWidth" format = " dimension" /> < attr name = " defaultContentColor" format = " color" /> < attr name = " bgBorderColor" format = " color" /> < attr name = " progressColor" format = " color" /> < attr name = " android:textColor" /> </ declare-styleable>
</ resources>
View(kotlin)源码
package com. example. testimport android. content. Context
import android. content. res. Resources
import android. graphics. Canvas
import android. graphics. Color
import android. graphics. Paint
import android. graphics. Rect
import android. util. AttributeSet
import android. util. TypedValue
import android. view. View
import kotlin. math. roundToIntclass ArcProgressView : View { constructor ( context: Context? ) : super ( context) constructor ( context: Context? , attrs: AttributeSet? ) : this ( context, attrs, 0 ) constructor ( context: Context? , attrs: AttributeSet? , defStyleAttr: Int) : super ( context, attrs, defStyleAttr) { val obtainStyledAttributes = context? . obtainStyledAttributes ( attrs, R. styleable. ArcProgressView) obtainStyledAttributes? . let { textSize = it. getDimensionPixelSize ( R. styleable. ArcProgressView_android_textSize, textSize) strokeWidth = it. getDimensionPixelSize ( R. styleable. ArcProgressView_bgBorderWidth, strokeWidth. roundToInt ( ) ) . toFloat ( ) defaultContentColor = it. getColor ( R. styleable. ArcProgressView_defaultContentColor, defaultContentColor) bgBorderColor = it. getColor ( R. styleable. ArcProgressView_bgBorderColor, bgBorderColor) progressColor = it. getColor ( R. styleable. ArcProgressView_progressColor, progressColor) textColor = it. getColor ( R. styleable. ArcProgressView_android_textColor, textColor) } obtainStyledAttributes? . recycle ( ) } val paint = Paint ( Paint. ANTI_ALIAS_FLAG) var strokeWidth = dpToPx ( 0.5f ) . toFloat ( ) ; var textSize = spToPx ( 10f ) . roundToInt ( ) var defaultContentColor = Color. parseColor ( "#FFF7ED" ) var bgBorderColor = Color. parseColor ( "#FAD29D" ) var progressColor = Color. parseColor ( "#FAD29D" ) var textColor = Color. parseColor ( "#FA940F" ) private var progress: Int = 0 set ( value) { field = valueinvalidate ( ) } override fun onDraw ( canvas: Canvas) { super . onDraw ( canvas) drawBackground ( canvas) drawProgress ( canvas) } private fun dpToPx ( dp: Float) : Int { return ( Resources. getSystem ( ) . displayMetrics. density * dp + 0.5f ) . roundToInt ( ) } private fun spToPx ( sp: Float) : Float { return TypedValue. applyDimension ( TypedValue. COMPLEX_UNIT_SP, sp, Resources. getSystem ( ) . displayMetrics) } private fun drawBackground ( canvas: Canvas) { paint. strokeWidth = strokeWidthpaint. style = Paint. Style. FILLpaint. color = defaultContentColorcanvas. drawOval ( 0f + strokeWidth / 2 , 0f + strokeWidth / 2 , width. toFloat ( ) - strokeWidth / 2 , height. toFloat ( ) - strokeWidth / 2 , paint) paint. style = Paint. Style. STROKEpaint. color = bgBorderColorcanvas. drawOval ( 0f + strokeWidth / 2 , 0f + strokeWidth / 2 , width. toFloat ( ) - strokeWidth / 2 , height. toFloat ( ) - strokeWidth / 2 , paint) } val textBound = Rect ( ) private fun drawProgress ( canvas: Canvas) { paint. style = Paint. Style. FILLpaint. color = progressColorpaint. textSize = textSize. toFloat ( ) val progressStr = " $ progress %" paint. getTextBounds ( progressStr, 0 , progressStr. length, textBound) val halfTextWidth = textBound. width ( ) / 2f val halfTextHeight = textBound. height ( ) / 2f val progressAngle = progress * 3.6f val halfWidth = width. toFloat ( ) / 2f val halfHeight = height. toFloat ( ) / 2f canvas. drawArc ( 0f , 0f , width. toFloat ( ) , height. toFloat ( ) , 270f , progressAngle, true , paint) paint. isFakeBoldText = true paint. color = textColorpaint. textAlign = Paint. Align. LEFTcanvas. drawText ( progressStr, halfWidth - halfTextWidth, halfHeight - halfTextHeight + textBound. height ( ) , paint) } fun updateProgress ( progress: Int) { this . progress = progress} }
Activity布局
< com.example.test.ArcProgressViewandroid: layout_margin= " 12dp" android: id= " @+id/progress" android: textSize= " 24sp" android: textColor= " @color/black" android: layout_width= " 100dp" android: layout_height= " 100dp" />
Activity更新进度
progress ++
runOnUiThread ( { progressView. updateProgress ( progress)
} )
效果图