image: new cover selection animation
This commit is contained in:
parent
59fd4b5e18
commit
89110c2798
2 changed files with 50 additions and 51 deletions
|
@ -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() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<Int, Int>,
|
||||
scaleOutDuration: Pair<Int, Int>,
|
||||
inInterpolator: Int,
|
||||
alphaInDuration: Pair<Int, Int>,
|
||||
scaleInDuration: Pair<Int, Int>
|
||||
) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue