From 8dc3b1f376742503017bca02794ad5625db0eea8 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:00:56 +0800 Subject: [PATCH] Restore secondary FAB fade --- .../com/hippo/ehviewer/ui/legacy/FabLayout.kt | 33 +++++++++++++++---- .../com/hippo/ehviewer/ui/main/FabLayout.kt | 14 +++++--- .../hippo/ehviewer/ui/scene/DownloadsScene.kt | 2 +- .../hippo/ehviewer/ui/tools/PredictiveBack.kt | 2 ++ 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/legacy/FabLayout.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/legacy/FabLayout.kt index 08b971917..c1922a8ed 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/legacy/FabLayout.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/legacy/FabLayout.kt @@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Close import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.SmallFloatingActionButton @@ -22,6 +22,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.vector.ImageVector @@ -50,6 +51,10 @@ class FabLayout @JvmOverloads constructor( var expanded by mutableStateOf(false) private val listeners = mutableListOf() + private var mHidden by mutableStateOf(hidden) + private var mExpanded by mutableStateOf(expanded) + private var showPrimaryFab by mutableStateOf(true) + fun addOnExpandStateListener(listener: OnExpandStateListener) { listeners.add(listener) } @@ -63,6 +68,12 @@ class FabLayout @JvmOverloads constructor( hidden = true } + fun hidePrimaryFab() { + mHidden = true + showPrimaryFab = false + hide() + } + @Composable override fun Content() { Mdc3Theme { @@ -86,23 +97,31 @@ class FabLayout @JvmOverloads constructor( val coroutineScope = rememberCoroutineScope() val appearState by animateFloatAsState( targetValue = if (hidden) 0f else 1f, - animationSpec = tween(FAB_ANIMATE_TIME), + animationSpec = tween(FAB_ANIMATE_TIME, if (mExpanded) FAB_ANIMATE_TIME else 0), label = "hiddenState", - ) + ) { mHidden = hidden } Box( modifier = Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.BottomEnd, ) { Box(contentAlignment = Alignment.Center) { - val animatedProgress by animateFloatMergePredictiveBackAsState(expanded) { expanded = false } + val animatedProgress by animateFloatMergePredictiveBackAsState( + enable = expanded, + animationSpec = tween(FAB_ANIMATE_TIME, if (mHidden) FAB_ANIMATE_TIME else 0), + finishedListener = { mExpanded = expanded }, + ) { expanded = false } FloatingActionButton( onClick = { expanded = !expanded }, modifier = Modifier.rotate(lerp(-90f, 0f, appearState)).scale(appearState), ) { Icon( - imageVector = Icons.Default.Add, + imageVector = Icons.Default.Close, contentDescription = null, - modifier = Modifier.rotate(lerp(135f, 0f, animatedProgress)), + modifier = if (showPrimaryFab) { + Modifier.rotate(lerp(0f, -135f, animatedProgress)) + } else { + Modifier + }, ) } secondaryFab?.run { @@ -122,7 +141,7 @@ class FabLayout @JvmOverloads constructor( val distance = lerp(150 * (size - index) + 50, 0, animatedProgress) placeable.placeRelative(0, -distance, -(size - index).toFloat()) } - }.rotate(lerp(90f, 0f, appearState)).scale(appearState), + }.alpha(1 - animatedProgress), ) { Icon(imageVector = imageVector, contentDescription = null) } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/FabLayout.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/FabLayout.kt index af59c7221..bbbffa8fb 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/FabLayout.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/FabLayout.kt @@ -9,7 +9,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Close import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.SmallFloatingActionButton @@ -19,6 +19,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.vector.ImageVector @@ -72,15 +73,18 @@ fun FabLayout( contentAlignment = Alignment.BottomEnd, ) { Box(contentAlignment = Alignment.Center) { - val animatedProgress by animateFloatMergePredictiveBackAsState(expanded) { onExpandChanged(false) } + val animatedProgress by animateFloatMergePredictiveBackAsState( + enable = expanded, + animationSpec = tween(FAB_ANIMATE_TIME), + ) { onExpandChanged(false) } FloatingActionButton( onClick = { onExpandChanged(!expanded) }, modifier = Modifier.rotate(lerp(-90f, 0f, appearState)).scale(appearState), ) { Icon( - imageVector = Icons.Default.Add, + imageVector = Icons.Default.Close, contentDescription = null, - modifier = Modifier.rotate(lerp(135f, 0f, animatedProgress)), + modifier = Modifier.rotate(lerp(0f, -135f, animatedProgress)), ) } secondaryFab.run { @@ -100,7 +104,7 @@ fun FabLayout( val distance = lerp(150 * (size - index) + 50, 0, animatedProgress) placeable.placeRelative(0, -distance, -(size - index).toFloat()) } - }.rotate(lerp(90f, 0f, appearState)).scale(appearState), + }.alpha(1 - animatedProgress), ) { Icon(imageVector = imageVector, contentDescription = null) } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/scene/DownloadsScene.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/scene/DownloadsScene.kt index 12f401910..ca41452c3 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/scene/DownloadsScene.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/scene/DownloadsScene.kt @@ -351,7 +351,7 @@ class DownloadsScene : SearchBarScene() { fastScroller.setHandlerDrawable(handlerDrawable) with(fabLayout) { autoCancel = false - hide() + hidePrimaryFab() addOnExpandStateListener { if (!it && tracker.isInCustomChoice) tracker.clearSelection() } secondaryFab = listOf( Icons.Default.DoneAll to { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/PredictiveBack.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/PredictiveBack.kt index 9727cf9f0..6bb446e39 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/PredictiveBack.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/PredictiveBack.kt @@ -31,6 +31,7 @@ import kotlinx.coroutines.CancellationException fun animateFloatMergePredictiveBackAsState( enable: Boolean, animationSpec: AnimationSpec = spring(), + finishedListener: ((Float) -> Unit)? = null, onBack: () -> Unit, ): State { // Natural animator state correspond with principal value @@ -38,6 +39,7 @@ fun animateFloatMergePredictiveBackAsState( targetValue = if (enable) 0f else 1f, animationSpec = animationSpec, label = "animationProgress", + finishedListener = finishedListener, ) // User predictive back animation progress holder && value correspond with UI State val ret = remember { mutableFloatStateOf(1F) }