Animate memory usage view

pull/311/head
Koitharu 3 years ago
parent b2266d47df
commit 1ad64f2710
No known key found for this signature in database
GPG Key ID: 8E861F8CE6E7CE27

@ -1,5 +1,7 @@
package org.koitharu.kotatsu.base.ui.widgets package org.koitharu.kotatsu.base.ui.widgets
import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Outline import android.graphics.Outline
@ -7,30 +9,36 @@ import android.graphics.Paint
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import android.view.ViewOutlineProvider import android.view.ViewOutlineProvider
import android.view.animation.DecelerateInterpolator
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.annotation.FloatRange import androidx.annotation.FloatRange
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import com.google.android.material.R as materialR
import kotlin.random.Random
import org.koitharu.kotatsu.parsers.util.replaceWith import org.koitharu.kotatsu.parsers.util.replaceWith
import org.koitharu.kotatsu.utils.ext.getAnimationDuration
import org.koitharu.kotatsu.utils.ext.getThemeColor import org.koitharu.kotatsu.utils.ext.getThemeColor
import org.koitharu.kotatsu.utils.ext.resolveDp import org.koitharu.kotatsu.utils.ext.resolveDp
import kotlin.random.Random
import com.google.android.material.R as materialR
class SegmentedBarView @JvmOverloads constructor( class SegmentedBarView @JvmOverloads constructor(
context: Context, context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0, defStyleAttr: Int = 0,
) : View(context, attrs, defStyleAttr) { ) : View(context, attrs, defStyleAttr), ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
private val paint = Paint(Paint.ANTI_ALIAS_FLAG) private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
private val segmentsData = ArrayList<Segment>() private val segmentsData = ArrayList<Segment>()
private val segmentsSizes = ArrayList<Float>() private val segmentsSizes = ArrayList<Float>()
private val outlineColor = context.getThemeColor(materialR.attr.colorOutline) private val outlineColor = context.getThemeColor(materialR.attr.colorOutline)
private var cornerSize = 0f private var cornerSize = 0f
private var scaleFactor = 1f
private var scaleAnimator: ValueAnimator? = null
var segments: List<Segment> var segments: List<Segment>
get() = segmentsData get() = segmentsData
set(value) { set(value) {
scaleAnimator?.cancel()
scaleAnimator = null
segmentsData.replaceWith(value) segmentsData.replaceWith(value)
updateSizes() updateSizes()
invalidate() invalidate()
@ -79,12 +87,47 @@ class SegmentedBarView @JvmOverloads constructor(
canvas.drawRoundRect(0f, 0f, w, height.toFloat(), cornerSize, cornerSize, paint) canvas.drawRoundRect(0f, 0f, w, height.toFloat(), cornerSize, cornerSize, paint)
} }
override fun onAnimationStart(animation: Animator) = Unit
override fun onAnimationEnd(animation: Animator) {
if (scaleAnimator === animation) {
scaleAnimator = null
}
}
override fun onAnimationUpdate(animation: ValueAnimator) {
scaleFactor = animation.animatedValue as Float
updateSizes()
invalidate()
}
override fun onAnimationCancel(animation: Animator) = Unit
override fun onAnimationRepeat(animation: Animator) = Unit
fun animateSegments(value: List<Segment>) {
scaleAnimator?.cancel()
scaleFactor = 0f
segmentsData.replaceWith(value)
updateSizes()
invalidate()
val animator = ValueAnimator.ofFloat(0f, 1f)
animator.duration = context.getAnimationDuration(android.R.integer.config_longAnimTime)
animator.interpolator = DecelerateInterpolator()
animator.addUpdateListener(this@SegmentedBarView)
animator.addListener(this@SegmentedBarView)
scaleAnimator = animator
animator.start()
}
private fun updateSizes() { private fun updateSizes() {
segmentsSizes.clear() segmentsSizes.clear()
segmentsSizes.ensureCapacity(segmentsData.size + 1) segmentsSizes.ensureCapacity(segmentsData.size + 1)
var w = width.toFloat() var w = width.toFloat()
for (segment in segmentsData) { val maxScale = (scaleFactor * (segments.size - 1)).coerceAtLeast(1f)
val segmentWidth = (w * segment.percent).coerceAtLeast(cornerSize) for ((index, segment) in segmentsData.withIndex()) {
val scale = (scaleFactor * (index + 1) / maxScale).coerceAtMost(1f)
val segmentWidth = (w * segment.percent).coerceAtLeast(cornerSize) * scale
segmentsSizes.add(segmentWidth) segmentsSizes.add(segmentWidth)
w -= segmentWidth w -= segmentWidth
} }

@ -40,7 +40,7 @@ class MemoryUsageView @JvmOverloads constructor(
val otherSegment = SegmentedBarView.Segment(usage?.otherCache?.percent ?: 0f, segmentColor(3)) val otherSegment = SegmentedBarView.Segment(usage?.otherCache?.percent ?: 0f, segmentColor(3))
with(binding) { with(binding) {
bar.segments = listOf(storageSegment, pagesSegment, otherSegment).filter { it.percent > 0f } bar.animateSegments(listOf(storageSegment, pagesSegment, otherSegment).filter { it.percent > 0f })
labelStorage.text = formatLabel(usage?.savedManga, R.string.saved_manga) labelStorage.text = formatLabel(usage?.savedManga, R.string.saved_manga)
labelPagesCache.text = formatLabel(usage?.pagesCache, R.string.pages_cache) labelPagesCache.text = formatLabel(usage?.pagesCache, R.string.pages_cache)
labelOtherCache.text = formatLabel(usage?.otherCache, R.string.other_cache) labelOtherCache.text = formatLabel(usage?.otherCache, R.string.other_cache)

Loading…
Cancel
Save