Finish predictive back from the scaled preview
This commit is contained in:
1 parent
14c13bae6d
commit
1ab46897c3
2 files changed
+39
-2
No files matched your search
@@ -12,6 +12,11 @@ are no binary releases; "version" tracks the shared `version` in the root build
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`identity`** — A committed predictive back no longer snaps the surface back
|
||||
to full size before it leaves. `Modifier.predictiveBack()` now holds the
|
||||
preview transform after `onBack`, and the new `predictiveBackExit()` exit
|
||||
fades and keeps shrinking from there; pair them on the surface's
|
||||
`AnimatedVisibility` instead of a full-size slide-out.
|
||||
- **`core-crash`** — The prefilled crash issue is filed in English again. Its
|
||||
title and body came from string resources, so a crash on a French phone
|
||||
opened the tracker with a French issue — unreadable to whoever has to triage
|
||||
|
||||
@@ -3,9 +3,12 @@ package de.jeanlucmakiola.floret.identity
|
||||
import android.provider.Settings
|
||||
import androidx.activity.BackEventCompat
|
||||
import androidx.activity.compose.PredictiveBackHandler
|
||||
import androidx.compose.animation.ExitTransition
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -19,6 +22,7 @@ import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
/**
|
||||
@@ -59,7 +63,11 @@ fun Modifier.animateContentSizeMotion(reduceMotion: Boolean = rememberReduceMoti
|
||||
* The standard Android predictive-back transform for a full-screen surface: as
|
||||
* the back gesture is dragged, the surface scales toward ~90%, shifts toward the
|
||||
* swiped edge and rounds its corners, previewing what's behind. Completing the
|
||||
* gesture invokes [onBack]; cancelling springs it back.
|
||||
* gesture invokes [onBack] and keeps the preview transform, so the surface
|
||||
* leaves from where the finger let go instead of snapping back to full size —
|
||||
* pair it with [predictiveBackExit] on the surface's own exit. Should the surface
|
||||
* still be there shortly after (the back was taken without dismissing it), it
|
||||
* settles back. Cancelling springs it back.
|
||||
*
|
||||
* A drop-in replacement for a screen's own `BackHandler(onBack)` — register it
|
||||
* once and apply the returned [Modifier] to that screen's root so the preview
|
||||
@@ -87,7 +95,8 @@ fun Modifier.predictiveBack(
|
||||
progress.snapTo(FastOutSlowInEasing.transform(event.progress))
|
||||
}
|
||||
onBack()
|
||||
progress.snapTo(0f)
|
||||
delay(COMMIT_SETTLE_DELAY_MILLIS)
|
||||
progress.animateTo(0f)
|
||||
} catch (_: CancellationException) {
|
||||
progress.animateTo(0f)
|
||||
}
|
||||
@@ -104,3 +113,26 @@ fun Modifier.predictiveBack(
|
||||
clip = p > 0f
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How long a committed preview is held before it settles back — past any exit
|
||||
* the surface would play, so it only fires for a back that left it in place.
|
||||
*/
|
||||
private const val COMMIT_SETTLE_DELAY_MILLIS = 1_000L
|
||||
|
||||
/**
|
||||
* The exit for a surface closed through [predictiveBack]: it fades while it keeps
|
||||
* shrinking from the preview's scale, rather than growing back and sliding off
|
||||
* at full size. Also reads right for a close without a gesture. Fade only under
|
||||
* reduced motion.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun predictiveBackExit(reduceMotion: Boolean = rememberReduceMotion()): ExitTransition {
|
||||
val fade = fadeOut(MaterialTheme.motionScheme.defaultEffectsSpec())
|
||||
return if (reduceMotion) {
|
||||
fade
|
||||
} else {
|
||||
fade + scaleOut(MaterialTheme.motionScheme.defaultSpatialSpec(), targetScale = 0.9f)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user