home: tune speed dial anim

This commit is contained in:
Alexander Capehart 2024-05-20 14:22:20 -06:00
parent b824ef40fb
commit 4e86a2f703
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47

View file

@ -40,6 +40,8 @@ import androidx.core.view.setMargins
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.widget.TextViewCompat import androidx.core.widget.TextViewCompat
import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.google.android.material.R as MR
import com.google.android.material.motion.MotionUtils
import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.MaterialShapeDrawable
import com.leinardi.android.speeddial.FabWithLabelView import com.leinardi.android.speeddial.FabWithLabelView
import com.leinardi.android.speeddial.SpeedDialActionItem import com.leinardi.android.speeddial.SpeedDialActionItem
@ -78,6 +80,13 @@ class ThemedSpeedDialView : SpeedDialView {
@AttrRes defStyleAttr: Int @AttrRes defStyleAttr: Int
) : super(context, attrs, defStyleAttr) ) : super(context, attrs, defStyleAttr)
private val matInterpolator =
MotionUtils.resolveThemeInterpolator(
context, MR.attr.motionEasingStandardInterpolator, FastOutSlowInInterpolator())
private val matDuration =
MotionUtils.resolveThemeDuration(context, MR.attr.motionDurationMedium2, 300)
init { init {
// Work around ripple bug on Android 12 when useCompatPadding = true. // Work around ripple bug on Android 12 when useCompatPadding = true.
// @see https://github.com/material-components/material-components-android/issues/2617 // @see https://github.com/material-components/material-components-android/issues/2617
@ -107,7 +116,7 @@ class ThemedSpeedDialView : SpeedDialView {
val mainFabDrawable = val mainFabDrawable =
RotateDrawable().apply { RotateDrawable().apply {
drawable = mainFab.drawable drawable = mainFab.drawable
toDegrees = mainFabAnimationRotateAngle toDegrees = 45f + 90f
} }
mainFabAnimationRotateAngle = 0f mainFabAnimationRotateAngle = 0f
setMainFabClosedDrawable(mainFabDrawable) setMainFabClosedDrawable(mainFabDrawable)
@ -116,6 +125,13 @@ class ThemedSpeedDialView : SpeedDialView {
override fun onMainActionSelected(): Boolean = false override fun onMainActionSelected(): Boolean = false
override fun onToggleChanged(isOpen: Boolean) { override fun onToggleChanged(isOpen: Boolean) {
mainFab.backgroundTintList =
ColorStateList.valueOf(
if (isOpen) mainFabClosedBackgroundColor
else mainFabOpenedBackgroundColor)
mainFab.imageTintList =
ColorStateList.valueOf(
if (isOpen) mainFabClosedIconColor else mainFabOpenedIconColor)
mainFabAnimator?.cancel() mainFabAnimator?.cancel()
mainFabAnimator = mainFabAnimator =
createMainFabAnimator(isOpen).apply { createMainFabAnimator(isOpen).apply {
@ -132,21 +148,43 @@ class ThemedSpeedDialView : SpeedDialView {
}) })
} }
private fun createMainFabAnimator(isOpen: Boolean): Animator = private fun createMainFabAnimator(isOpen: Boolean): Animator {
AnimatorSet().apply { val totalDuration = matDuration.toLong()
playTogether( val partialDuration = totalDuration / 2 // This is half of the total duration
val delay = totalDuration / 4 // This is one fourth of the total duration
val backgroundTintAnimator =
ObjectAnimator.ofArgb( ObjectAnimator.ofArgb(
mainFab, mainFab,
VIEW_PROPERTY_BACKGROUND_TINT, VIEW_PROPERTY_BACKGROUND_TINT,
if (isOpen) mainFabOpenedBackgroundColor else mainFabClosedBackgroundColor), if (isOpen) mainFabOpenedBackgroundColor else mainFabClosedBackgroundColor)
.apply {
startDelay = delay
duration = partialDuration
}
val imageTintAnimator =
ObjectAnimator.ofArgb( ObjectAnimator.ofArgb(
mainFab, mainFab,
IMAGE_VIEW_PROPERTY_IMAGE_TINT, IMAGE_VIEW_PROPERTY_IMAGE_TINT,
if (isOpen) mainFabOpenedIconColor else mainFabClosedIconColor), if (isOpen) mainFabOpenedIconColor else mainFabClosedIconColor)
.apply {
startDelay = delay
duration = partialDuration
}
val levelAnimator =
ObjectAnimator.ofInt( ObjectAnimator.ofInt(
mainFab.drawable, DRAWABLE_PROPERTY_LEVEL, if (isOpen) 10000 else 0)) mainFab.drawable, DRAWABLE_PROPERTY_LEVEL, if (isOpen) 10000 else 0)
duration = 200 .apply { duration = totalDuration }
interpolator = FastOutSlowInInterpolator()
val animatorSet =
AnimatorSet().apply {
playTogether(backgroundTintAnimator, imageTintAnimator, levelAnimator)
interpolator = matInterpolator
}
animatorSet.start()
return animatorSet
} }
override fun onAttachedToWindow() { override fun onAttachedToWindow() {