-
-
Save AndrewKhaynus/0cca8abf7b4035849046de03fca31367 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.animation.TimeInterpolator | |
import android.content.Context | |
import android.graphics.* | |
import android.util.AttributeSet | |
import android.view.View | |
import android.graphics.Shader | |
import android.animation.ValueAnimator | |
import android.view.animation.LinearInterpolator | |
import androidx.annotation.ColorInt | |
class GradientProgressBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) | |
: View(context, attrs, defStyleAttr) { | |
@ColorInt private val yellow = -0x006300 | |
@ColorInt private val orange = -0x0021E9 | |
@ColorInt private val grey = -0x8F8F8F | |
private val rotationAngle = 30f | |
private val speedMultiplier = 1.2 | |
private val gradientLength = 150f | |
private val animationDuration = 500L | |
private val backgroundRect = RectF() | |
private val progressRect = RectF() | |
private var parentWidth = 0f | |
private var parentHeight = 0f | |
private var matrixTransitionOffset = 0f | |
set(value) { | |
field = value | |
postInvalidateOnAnimation() | |
} | |
private var transitionAnimator: ValueAnimator? = null | |
private var progressAnimator: ValueAnimator? = null | |
private val paint = Paint() | |
private val progressPaint = Paint() | |
private val shader = createShader() | |
private val transformMatrix = Matrix() | |
private var percentProgress = 0f | |
set(value) { | |
field = value | |
invalidate() | |
} | |
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec) | |
parentWidth = MeasureSpec.getSize(widthMeasureSpec).toFloat() | |
parentHeight = MeasureSpec.getSize(heightMeasureSpec).toFloat() | |
progressPaint.isAntiAlias = true | |
progressPaint.style = Paint.Style.FILL | |
paint.style = Paint.Style.FILL | |
paint.isAntiAlias = true | |
backgroundRect.set(0f, 0f, parentWidth, parentHeight) | |
} | |
override fun onDraw(canvas: Canvas?) { | |
super.onDraw(canvas) | |
paint.color = grey | |
canvas?.drawRoundRect(backgroundRect, parentHeight/2, parentHeight/2, paint) | |
transformMatrix.setTranslate(matrixTransitionOffset, 0f) | |
transformMatrix.postRotate(rotationAngle) | |
shader.setLocalMatrix(transformMatrix) | |
progressPaint.shader = shader | |
progressRect.set(0f, 0f, (parentWidth/100) * percentProgress, parentHeight) | |
canvas?.drawRoundRect(progressRect, parentHeight/2, parentHeight/2, progressPaint) | |
} | |
private fun createShader(): Shader { | |
return LinearGradient(0f, 0f, gradientLength, parentHeight, yellow, orange, Shader.TileMode.REPEAT) | |
} | |
override fun onAttachedToWindow() { | |
super.onAttachedToWindow() | |
transitionAnimator = ValueAnimator.ofFloat(0f, gradientLength).apply { | |
addUpdateListener { matrixTransitionOffset = it.animatedValue as Float } | |
duration = (animationDuration * speedMultiplier).toLong() | |
repeatMode = ValueAnimator.RESTART | |
repeatCount = ValueAnimator.INFINITE | |
interpolator = LinearInterpolator() | |
start() | |
} | |
} | |
override fun onDetachedFromWindow() { | |
transitionAnimator?.cancel() | |
progressAnimator?.cancel() | |
super.onDetachedFromWindow() | |
} | |
fun setProgress(progress: Float, | |
duration: Long = animationDuration, | |
interpolator: TimeInterpolator = LinearInterpolator()) { | |
progressAnimator?.end() | |
progressAnimator = ValueAnimator.ofFloat(percentProgress, progress).apply { | |
addUpdateListener { percentProgress = it.animatedValue as Float } | |
this.duration = duration | |
this.interpolator = interpolator | |
start() | |
} | |
} | |
fun getProgress(): Float { | |
return percentProgress | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment