Skip to content

Instantly share code, notes, and snippets.

@Stickerbox
Created December 10, 2017 15:38
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Stickerbox/040fd6be8b77009a05f454d9d31f0786 to your computer and use it in GitHub Desktop.
import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.support.annotation.ColorRes
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
class ProgressView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0) : View(context, attrs, defStyleAttr, defStyleRes) {
private val trackPaint = Paint()
private val progressPaint = Paint()
private val rectF = RectF()
private var progress = 0.0
private var animation: ValueAnimator? = null
private val animatorListener = object : Animator.AnimatorListener {
override fun onAnimationRepeat(p0: Animator?) {
}
override fun onAnimationCancel(p0: Animator?) {
}
override fun onAnimationStart(p0: Animator?) {
}
override fun onAnimationEnd(p0: Animator?) {
onAnimationFinished?.invoke()
}
}
@ColorRes
var trackColor = Color.LTGRAY
@ColorRes
var progressColor = Color.GRAY
var trackWidth = 15f
var onAnimationFinished: (() -> Unit)? = null
init {
val trackWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, trackWidth, resources.displayMetrics)
trackPaint.color = trackColor
trackPaint.isAntiAlias = true
trackPaint.style = Paint.Style.STROKE
trackPaint.strokeWidth = trackWidth
progressPaint.color = progressColor
progressPaint.isAntiAlias = true
progressPaint.style = Paint.Style.STROKE
progressPaint.strokeWidth = trackWidth
progressPaint.strokeCap = Paint.Cap.ROUND
}
fun setProgress(newProgress: Double, duration: Long = 500) {
animation?.cancel()
animation = ValueAnimator.ofFloat(progress.toFloat(), newProgress.toFloat())
animation?.duration = duration
animation?.addUpdateListener {
progress = (it.animatedValue as Float).toDouble()
invalidate()
}
animation?.addListener(animatorListener)
animation?.start()
invalidate()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val longestSide = if (measuredHeight < measuredWidth) measuredHeight else measuredWidth
val arcBounds = (longestSide * (0.004 * trackWidth)).toInt()
rectF.set(arcBounds.toFloat(), arcBounds.toFloat(), (longestSide - arcBounds).toFloat(), (longestSide - arcBounds).toFloat())
}
override fun onDraw(canvas: Canvas?) {
canvas?.drawArc(rectF, -90f, 360f, false, trackPaint)
canvas?.drawArc(rectF, -90f, 360f / 100 * (progress.toFloat()), false, progressPaint)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment