Skip to content

Commit

Permalink
ver 1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
muramrr committed Aug 18, 2020
1 parent 4a9ef1f commit 55d75bf
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 35 deletions.
75 changes: 42 additions & 33 deletions loadingview/src/main/java/com/mmdev/loadingviewlib/LoadingView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import android.content.res.Resources
import androidx.core.view.animation.PathInterpolatorCompat
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.animation.ValueAnimator.*
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
Expand All @@ -32,6 +31,7 @@ import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator
import kotlin.math.max
import kotlin.math.min

/*
Expand All @@ -41,19 +41,21 @@ import kotlin.math.min
class LoadingView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) {
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

private val ovalRectF = RectF()
private val sweepPaint = Paint().apply {
isAntiAlias = true
style = Paint.Style.STROKE
strokeCap = Paint.Cap.ROUND
}
private var sweepPaintShadowRadius = 0f

private var minStrokeSize = 4.toPx()
private var minStrokeSize = 2.toPx()
private var maxStrokeSize = 8.toPx()

/** force stroke to be in bounds min 4dp and max 8dp
/** force stroke to be in bounds min 2dp and max 8dp
* also auto apply [sweepPaint] strokeWidth
* @see minStrokeSize
* @see maxStrokeSize
Expand All @@ -66,8 +68,11 @@ class LoadingView @JvmOverloads constructor(
else -> value
}
sweepPaint.strokeWidth = field.toFloat()
sweepPaintShadowRadius = field * 1.25f
sweepPaint.setShadowLayer(sweepPaintShadowRadius,0f,0f, sweepColor)
}

//starting angles of 3 sweeps
private var sweepAngle1 = 5f
private var sweepAngle2 = 5f
private var sweepAngle3 = 5f
Expand All @@ -78,11 +83,38 @@ class LoadingView @JvmOverloads constructor(
private set(value) {
field = value
sweepPaint.color = field
sweepPaint.setShadowLayer(10f,0f,0f, field)
sweepPaint.setShadowLayer(sweepPaintShadowRadius,0f,0f, field)
}

private val animatorSet = AnimatorSet()

//rotating whole view
private val viewRotateAnimator = ValueAnimator.ofFloat(0f, 360f).apply {
duration = 1600
interpolator = LinearInterpolator()
repeatCount = ValueAnimator.INFINITE
repeatMode = ValueAnimator.RESTART
addUpdateListener { rotation = it.animatedValue as Float }
}

//animate 3 sweeps inside view
private val angleAnimator = ValueAnimator.ofFloat(5f, 105f).apply {
duration = 800
// god given custom interpolator
interpolator = PathInterpolatorCompat.create(1f, 0f, 0f, 1f)
repeatCount = ValueAnimator.INFINITE
repeatMode = ValueAnimator.REVERSE
addUpdateListener {

sweepAngle1 = it.animatedValue as Float
sweepAngle2 = it.animatedValue as Float
sweepAngle3 = it.animatedValue as Float
invalidate()

}

}

/** using for toggle animation
* true -> animatorSet.resume()
* false -> animatorSet.pause()
Expand All @@ -106,7 +138,7 @@ class LoadingView @JvmOverloads constructor(

sweepColor = ta.getColor(R.styleable.LoadingView_loadStrokeColor, Color.WHITE)

strokeSize = ta.getDimensionPixelSize(R.styleable.LoadingView_loadStrokeWidth, 8)
strokeSize = ta.getDimensionPixelSize(R.styleable.LoadingView_loadStrokeWidth, minStrokeSize)

ta.recycle()
}
Expand All @@ -119,7 +151,9 @@ class LoadingView @JvmOverloads constructor(
val height = MeasureSpec.getSize(heightMeasureSpec)

//check the lowest value to draw square
val minSize = min(width, height)
val minSize = min(width, height).also {
strokeSize = max(minStrokeSize, min(maxStrokeSize, it / 24))
}

//calculate bounds to draw without cutting off
ovalRectF.set(paddingLeft.toFloat() + strokeSize,
Expand All @@ -133,7 +167,7 @@ class LoadingView @JvmOverloads constructor(
// auto start animation on pre-draw stage
// no need to toggle
animatorSet.cancel()
animatorSet.playTogether(angleAnimator(), viewRotateAnimator())
animatorSet.playTogether(angleAnimator, viewRotateAnimator)
animatorSet.start()
}

Expand All @@ -149,31 +183,6 @@ class LoadingView @JvmOverloads constructor(
isAnimating = !isAnimating
}

private fun angleAnimator() = ValueAnimator.ofFloat(5f, 100f).apply {
duration = 800
// god given custom interpolator
interpolator = PathInterpolatorCompat.create(1f, 0f, 0f, 1f)
repeatCount = INFINITE
repeatMode = REVERSE
addUpdateListener {

sweepAngle1 = it.animatedValue as Float
sweepAngle2 = it.animatedValue as Float
sweepAngle3 = it.animatedValue as Float
invalidate()

}

}

private fun viewRotateAnimator() = ValueAnimator.ofFloat(0f, 360f).apply {
duration = 1600
interpolator = LinearInterpolator()
repeatCount = INFINITE
repeatMode = RESTART
addUpdateListener { rotation = it.animatedValue as Float }
}

private fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()

private fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()
Expand Down
4 changes: 2 additions & 2 deletions loadingview/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
-->

<resources>

<declare-styleable name="LoadingView">
<attr name="loadStrokeColor" format="color" />
<attr name="loadStrokeColor" format="color|reference" />
<attr name="loadStrokeWidth" format="dimension"/>
</declare-styleable>

Expand Down

0 comments on commit 55d75bf

Please sign in to comment.