Advertisement
leptodon

bar

Dec 4th, 2020
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 8.00 KB | None | 0 0
  1. package ru.cactus.progressbar.animation
  2.  
  3. import android.animation.AnimatorSet
  4. import android.animation.ObjectAnimator
  5. import android.animation.ValueAnimator
  6. import android.content.Context
  7. import android.graphics.*
  8. import android.util.AttributeSet
  9. import android.util.DisplayMetrics
  10. import android.util.TypedValue
  11. import android.view.View
  12. import android.view.animation.LinearInterpolator
  13. import androidx.core.content.res.ResourcesCompat
  14. import ru.cactus.progressbar.R
  15. import kotlin.properties.Delegates
  16.  
  17. class CustomProgressBar @JvmOverloads constructor(
  18.     context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
  19. ) : View(context, attrs, defStyleAttr) {
  20.  
  21.     private var mBodyStrokeWidthPx by Delegates.notNull<Float>()
  22.     private var mGlowStrokeWidthPx by Delegates.notNull<Float>()
  23.     private var mPaddingPx by Delegates.notNull<Float>()
  24.  
  25.     private var mPaintBody: Paint = Paint()
  26.     private var mPaintBackground: Paint = Paint()
  27.     private var mPaintOrangeBackground: Paint = Paint()
  28.     private var mPaintGlow: Paint = Paint()
  29.     private var mRect: RectF
  30.     private lateinit var mBodyGradient: SweepGradient
  31.     private var mBodyGradientFromToColors: IntArray
  32.     private var mGradientFromToPositions: FloatArray
  33.     private var currentAngle by Delegates.notNull<Float>()
  34.     private lateinit var animatorSet: AnimatorSet
  35.  
  36.     private var currentColor by Delegates.notNull<Int>()
  37.  
  38.     private val backgroundColor: Int = ResourcesCompat.getColor(resources, R.color.background_color, null)
  39.     private val blueColor: Int = ResourcesCompat.getColor(resources, R.color.blue, null)
  40.     private val orangeColor: Int = ResourcesCompat.getColor(resources, R.color.orange, null)
  41.  
  42.     private var drawState:Int = 0
  43.  
  44.  
  45.     companion object {
  46.         private const val BODY_STROKE_WIDTH: Int = 6
  47.         private const val GLOW_STROKE_WIDTH: Int = 6
  48.         private const val PADDING: Int = GLOW_STROKE_WIDTH / 2 + BODY_STROKE_WIDTH
  49.         private const val BODY_LENGTH: Float = 240f
  50.         private const val NORMALIZED_GRADIENT_LENGTH: Float = BODY_LENGTH / 480f
  51.         private const val ROTATION_LENGTH: Float = 360f
  52.         private const val ROTATION_DURATION: Long = 2000
  53.         private const val TAIL_GROW_DURATION: Long = 4000
  54.         private const val ROTATION_PROPERTY_NAME: String = "rotation"
  55.     }
  56.  
  57.     init {
  58.         setLayerType(LAYER_TYPE_SOFTWARE, null)
  59.         val displayMetrics: DisplayMetrics = resources.displayMetrics
  60.  
  61.         currentAngle = 10f
  62.  
  63.         mBodyStrokeWidthPx = TypedValue.applyDimension(
  64.             TypedValue.COMPLEX_UNIT_DIP,
  65.             BODY_STROKE_WIDTH.toFloat(),
  66.             displayMetrics
  67.         )
  68.         mPaddingPx = TypedValue.applyDimension(
  69.             TypedValue.COMPLEX_UNIT_DIP,
  70.             PADDING.toFloat(),
  71.             displayMetrics
  72.         )
  73.         mGlowStrokeWidthPx = TypedValue.applyDimension(
  74.             TypedValue.COMPLEX_UNIT_DIP,
  75.             GLOW_STROKE_WIDTH.toFloat(),
  76.             displayMetrics
  77.         )
  78.  
  79.         currentColor = blueColor
  80.  
  81.         mPaintBackground.color = backgroundColor
  82.         mPaintBackground.strokeWidth = mBodyStrokeWidthPx
  83.         mPaintBackground.style = Paint.Style.STROKE
  84.  
  85.         mPaintOrangeBackground.color = orangeColor
  86.         mPaintOrangeBackground.strokeWidth = mBodyStrokeWidthPx
  87.         mPaintOrangeBackground.style = Paint.Style.STROKE
  88.  
  89.         mRect = RectF()
  90.  
  91.         mPaintBody.isAntiAlias = true
  92.         mPaintBody.color = currentColor
  93.         mPaintBody.strokeWidth = mBodyStrokeWidthPx
  94.         mPaintBody.style = Paint.Style.STROKE
  95.         mPaintBody.strokeJoin = Paint.Join.ROUND
  96.         mPaintBody.strokeCap = Paint.Cap.ROUND
  97.  
  98.         mPaintGlow.set(mPaintBody)
  99.         mPaintGlow.color = currentColor
  100.         mPaintGlow.strokeWidth = mGlowStrokeWidthPx
  101.         mPaintGlow.alpha = 200
  102.         mPaintGlow.maskFilter = BlurMaskFilter(mBodyStrokeWidthPx, BlurMaskFilter.Blur.OUTER)
  103.  
  104.         mBodyGradientFromToColors = intArrayOf(Color.TRANSPARENT, currentColor)
  105.         mGradientFromToPositions = floatArrayOf(0F, NORMALIZED_GRADIENT_LENGTH)
  106.     }
  107.  
  108.     fun handlerState(state: EngineState) {
  109.         when (state) {
  110.             EngineState.START -> cleanStart()
  111.             EngineState.START_SUCCESS -> changeColor()
  112.             EngineState.START_TIMEOUT -> changeColorAndStop()
  113.             EngineState.STOP -> TODO()
  114.             EngineState.STOP_SUCCESS -> TODO()
  115.             EngineState.STOP_TIMEOUT -> TODO()
  116.         }
  117.     }
  118.  
  119.     private fun growTail() {
  120.         Thread(Runnable {
  121.             kotlin.run {
  122.                 for (i in 30..BODY_LENGTH.toInt()) {
  123.                     currentAngle = i.toFloat()
  124.                     try {
  125.                         Thread.sleep(16)
  126.                     } catch (e: Exception) {
  127.                         e.printStackTrace()
  128.                     }
  129.                 }
  130.             }
  131.         }).start()
  132.     }
  133.  
  134.     override fun onDraw(canvas: Canvas?) {
  135.         val left: Float = mPaddingPx
  136.         val top: Float = mPaddingPx
  137.         val right: Float = width - mPaddingPx
  138.         val bottom: Float = height - mPaddingPx
  139.         mRect.set(left, top, right, bottom)
  140.         canvas?.rotate(rotation, (width / 2).toFloat(), (height / 2).toFloat())
  141.         when (drawState) {
  142.             0 -> {
  143.                 canvas?.drawArc(mRect, 0f, 360f, false, mPaintBackground)
  144.                 canvas?.drawArc(mRect, 10f, currentAngle, false, mPaintBody)
  145.                 canvas?.drawArc(mRect, currentAngle+10f, -10f, false, mPaintGlow)
  146.             }
  147.             1 -> {
  148.                 canvas?.drawArc(mRect, 0f, 360f, false, mPaintBackground)
  149.             }
  150.         }
  151.         mDraw(canvas)
  152.         postInvalidateOnAnimation()
  153.     }
  154.  
  155.     fun mDraw(canvas: Canvas?) {
  156.         if (canvas == null) {
  157.             return
  158.         }
  159.     }
  160.  
  161.     override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
  162.         super.onSizeChanged(w, h, oldw, oldh)
  163.         val centerX: Float = (width / 2).toFloat()
  164.         val centerY: Float = (height / 2).toFloat()
  165.         mBodyGradient =
  166.             SweepGradient(centerX, centerY, mBodyGradientFromToColors, mGradientFromToPositions)
  167.         mPaintBody.shader = mBodyGradient
  168. //        mPaintGlow.shader = mBodyGradient
  169.     }
  170.  
  171.  
  172.     private fun createRotationAnimator(): ObjectAnimator {
  173.         val rotateAnimator: ObjectAnimator =
  174.             ObjectAnimator.ofFloat(this, ROTATION_PROPERTY_NAME, ROTATION_LENGTH)
  175.         rotateAnimator.duration = ROTATION_DURATION
  176.         rotateAnimator.interpolator = LinearInterpolator()
  177.         rotateAnimator.repeatMode = ValueAnimator.RESTART
  178.         rotateAnimator.repeatCount = ValueAnimator.INFINITE
  179.         return rotateAnimator
  180.     }
  181.  
  182.     private fun createGrowTailAnimator(): ValueAnimator {
  183.         val growAnimator: ValueAnimator = ValueAnimator.ofFloat(currentAngle, currentAngle + 270f)
  184.         growAnimator.addUpdateListener {
  185.             ValueAnimator.AnimatorUpdateListener { animation ->
  186.                 currentAngle = animation.animatedValue as Float
  187.             }
  188.         }
  189.         growAnimator.duration = TAIL_GROW_DURATION
  190.         growAnimator.repeatCount = 1
  191.         growAnimator.interpolator = LinearInterpolator()
  192.         return growAnimator
  193.     }
  194.  
  195.     private fun cleanStart() {
  196.         animatorSet = AnimatorSet()
  197.         animatorSet.play(createGrowTailAnimator()).with(createRotationAnimator())
  198.         animatorSet.duration = 4000
  199.         animatorSet.start()
  200.         growTail()
  201.     }
  202.  
  203.     private fun changeColor() {
  204.         currentColor = orangeColor
  205.         mPaintBody.color = orangeColor
  206.         mPaintGlow.color = orangeColor
  207.         mBodyGradientFromToColors = intArrayOf(Color.TRANSPARENT, orangeColor)
  208.         onSizeChanged(width,height,width,height)
  209.     }
  210.  
  211.     private fun changeColorAndStop(){
  212.         mPaintBackground.color = orangeColor
  213.         drawState = 1
  214.         invalidate()
  215.     }
  216. }
  217.  
  218. enum class EngineState {
  219.     START,
  220.     START_SUCCESS,
  221.     START_TIMEOUT,
  222.     STOP,
  223.     STOP_SUCCESS,
  224.     STOP_TIMEOUT
  225. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement