diff --git a/app/src/main/java/org/oxycblt/auxio/image/CoverView.kt b/app/src/main/java/org/oxycblt/auxio/image/CoverView.kt index faa3ecb04..29248f195 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/CoverView.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/CoverView.kt @@ -18,7 +18,7 @@ package org.oxycblt.auxio.image -import android.animation.ValueAnimator +import android.animation.Animator import android.annotation.SuppressLint import android.content.Context import android.graphics.Canvas @@ -56,12 +56,12 @@ import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Playlist import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.ui.MaterialFader import org.oxycblt.auxio.ui.UISettings import org.oxycblt.auxio.util.getAttrColorCompat import org.oxycblt.auxio.util.getColorCompat import org.oxycblt.auxio.util.getDimenPixels import org.oxycblt.auxio.util.getDrawableCompat -import org.oxycblt.auxio.util.getInteger /** * Auxio's extension of [ImageView] that enables cover art loading and playing indicator and @@ -93,7 +93,8 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr private val selectionBadge: ImageView? private val iconSize: Int? - private var fadeAnimator: ValueAnimator? = null + private val fader = MaterialFader.forSmallComponent(context) + private var fadeAnimator: Animator? = null private val indicatorMatrix = Matrix() private val indicatorMatrixSrc = RectF() private val indicatorMatrixDst = RectF() @@ -294,43 +295,10 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr } private fun invalidateSelectionIndicatorAlpha(selectionBadge: ImageView) { - // Set up a target transition for the selection indicator. - val targetAlpha: Float - val targetDuration: Long - - if (isActivated) { - // View is "activated" (i.e marked as selected), so show the selection indicator. - targetAlpha = 1f - targetDuration = context.getInteger(R.integer.anim_fade_enter_duration).toLong() - } else { - // View is not "activated", hide the selection indicator. - targetAlpha = 0f - targetDuration = context.getInteger(R.integer.anim_fade_exit_duration).toLong() - } - - if (selectionBadge.alpha == targetAlpha) { - // Nothing to do. - return - } - - if (!isLaidOut) { - // Not laid out, initialize it without animation before drawing. - selectionBadge.alpha = targetAlpha - return - } - - if (fadeAnimator != null) { - // Cancel any previous animation. - fadeAnimator?.cancel() - fadeAnimator = null - } - + fadeAnimator?.cancel() fadeAnimator = - ValueAnimator.ofFloat(selectionBadge.alpha, targetAlpha).apply { - duration = targetDuration - addUpdateListener { selectionBadge.alpha = it.animatedValue as Float } - start() - } + (if (isActivated) fader.fadeIn(selectionBadge) else fader.fadeOut(selectionBadge)) + .also { it.start() } } /** diff --git a/app/src/main/java/org/oxycblt/auxio/ui/Animations.kt b/app/src/main/java/org/oxycblt/auxio/ui/Animations.kt index db54ba9eb..86d2f06fd 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/Animations.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/Animations.kt @@ -97,12 +97,21 @@ class MaterialCornerAnim(context: Context) { } } -class MaterialFader private constructor(context: Context, private val scale: Float) { - private val alphaOutConfig = - AnimConfig.of(context, AnimConfig.EMPHASIZED_ACCELERATE, AnimConfig.SHORT3) - private val scaleOutConfig = - AnimConfig.of(context, AnimConfig.EMPHASIZED_ACCELERATE, AnimConfig.MEDIUM1) - private val inConfig = AnimConfig.of(context, AnimConfig.EMPHASIZED, AnimConfig.LONG2) +class MaterialFader +private constructor( + context: Context, + private val scale: Float, + @AttrRes outInterpolator: Int, + alphaOutDuration: Pair, + scaleOutDuration: Pair, + inInterpolator: Int, + alphaInDuration: Pair, + scaleInDuration: Pair +) { + private val alphaOutConfig = AnimConfig.of(context, outInterpolator, alphaOutDuration) + private val scaleOutConfig = AnimConfig.of(context, outInterpolator, scaleOutDuration) + private val alphaInConfig = AnimConfig.of(context, inInterpolator, alphaInDuration) + private val scaleInConfig = AnimConfig.of(context, inInterpolator, scaleInDuration) fun jumpToFadeOut(view: View) { view.apply { @@ -128,7 +137,11 @@ class MaterialFader private constructor(context: Context, private val scale: Flo return AnimatorSet() } - val alphaAnimator = alphaOutConfig.genericFloat(view.alpha, 0f) { view.alpha = it } + val alphaAnimator = + alphaOutConfig.genericFloat(view.alpha, 0f) { + view.alpha = it + view.isInvisible = view.alpha == 0f + } val scaleXAnimator = scaleOutConfig.genericFloat(view.scaleX, scale) { view.scaleX = it } val scaleYAnimator = scaleOutConfig.genericFloat(view.scaleY, scale) { view.scaleY = it } return AnimatorSet().apply { playTogether(alphaAnimator, scaleXAnimator, scaleYAnimator) } @@ -140,19 +153,37 @@ class MaterialFader private constructor(context: Context, private val scale: Flo return AnimatorSet() } val alphaAnimator = - inConfig.genericFloat(view.alpha, 1f) { + alphaInConfig.genericFloat(view.alpha, 1f) { view.alpha = it view.isInvisible = view.alpha == 0f } - val scaleXAnimator = inConfig.genericFloat(view.scaleX, 1.0f) { view.scaleX = it } - val scaleYAnimator = inConfig.genericFloat(view.scaleY, 1.0f) { view.scaleY = it } + val scaleXAnimator = scaleInConfig.genericFloat(view.scaleX, 1.0f) { view.scaleX = it } + val scaleYAnimator = scaleInConfig.genericFloat(view.scaleY, 1.0f) { view.scaleY = it } return AnimatorSet().apply { playTogether(alphaAnimator, scaleXAnimator, scaleYAnimator) } } companion object { - fun forSmallComponent(context: Context) = MaterialFader(context, 0.4f) + fun forSmallComponent(context: Context) = + MaterialFader( + context, + 0.6f, + AnimConfig.EMPHASIZED_ACCELERATE, + AnimConfig.SHORT1, + AnimConfig.SHORT3, + AnimConfig.EMPHASIZED_DECELERATE, + AnimConfig.SHORT1, + AnimConfig.MEDIUM3) - fun forLargeComponent(context: Context) = MaterialFader(context, 0.9f) + fun forLargeComponent(context: Context) = + MaterialFader( + context, + 0.9f, + AnimConfig.EMPHASIZED_ACCELERATE, + AnimConfig.SHORT3, + AnimConfig.MEDIUM1, + AnimConfig.EMPHASIZED, + AnimConfig.LONG2, + AnimConfig.LONG2) } }