Skip to content

Instantly share code, notes, and snippets.

@robertlevonyan
Created March 30, 2021 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertlevonyan/bd5615e9f25d92de81fbdbf40a659bd8 to your computer and use it in GitHub Desktop.
Save robertlevonyan/bd5615e9f25d92de81fbdbf40a659bd8 to your computer and use it in GitHub Desktop.
package com.robertlevonyan.demo.progressbar
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import androidx.core.animation.doOnEnd
class ProgressBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : View(context, attrs, defStyleAttr, defStyleRes) {
companion object {
private const val INITIAL_WIDTH = 10f
private const val TARGET_WIDTH = 200f
}
private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.LTGRAY
}
private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.YELLOW
}
private var progressLeft = INITIAL_WIDTH
private var progressRight = INITIAL_WIDTH
private val widthStartAnimation by lazy {
ValueAnimator.ofFloat(progressLeft, TARGET_WIDTH).apply {
duration = 300
addUpdateListener {
progressRight = it.animatedValue as Float
invalidate()
}
}
}
private val translateAnimation by lazy {
val end = width - 10 - TARGET_WIDTH
ValueAnimator.ofFloat(progressLeft, end).apply {
duration = 800
startDelay = 250
addUpdateListener {
val translationValue = it.animatedValue as Float
progressLeft = translationValue
progressRight = translationValue + TARGET_WIDTH
invalidate()
}
}
}
private val widthEndAnimation by lazy {
ValueAnimator.ofFloat(TARGET_WIDTH, INITIAL_WIDTH).apply {
startDelay = 1000
addUpdateListener {
progressLeft = width - it.animatedValue as Float
invalidate()
}
}
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas ?: return
val (left, top) = INITIAL_WIDTH to height / 2f + INITIAL_WIDTH
val (right, bottom) = width - INITIAL_WIDTH to height / 2f - INITIAL_WIDTH
val (rx, ry) = height / 2f to height / 2f
// draw background
canvas.drawRoundRect(left, top, right, bottom, rx, ry, bgPaint)
// draw progress
canvas.drawRoundRect(progressLeft, top, progressRight, bottom, rx, ry, progressPaint)
}
fun startAnimation() {
post {
AnimatorSet()
.apply {
playTogether(widthStartAnimation, translateAnimation, widthEndAnimation)
doOnEnd {
progressLeft = INITIAL_WIDTH
progressRight = INITIAL_WIDTH
it.start()
}
}
.start()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment