summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt26
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt15
2 files changed, 32 insertions, 9 deletions
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index 974442494181..141736f46ee4 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -29,6 +29,7 @@ import com.android.compose.nestedscroll.PriorityNestedScrollConnection
import com.android.compose.nestedscroll.ScrollController
import com.android.compose.ui.util.SpaceVectorConverter
import kotlin.math.absoluteValue
+import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -359,13 +360,24 @@ private class DragControllerImpl(
return swipeAnimation.animateOffset(velocity, targetContent)
}
- overscrollEffect.applyToFling(
- velocity = velocity.toVelocity(),
- performFling = {
- val velocityLeft = it.toFloat()
- swipeAnimation.animateOffset(velocityLeft, targetContent).toVelocity()
- },
- )
+ val overscrollCompletable = CompletableDeferred<Unit>()
+ try {
+ overscrollEffect.applyToFling(
+ velocity = velocity.toVelocity(),
+ performFling = {
+ val velocityLeft = it.toFloat()
+ swipeAnimation
+ .animateOffset(
+ velocityLeft,
+ targetContent,
+ overscrollCompletable = overscrollCompletable,
+ )
+ .toVelocity()
+ },
+ )
+ } finally {
+ overscrollCompletable.complete(Unit)
+ }
return velocity
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
index 5aaeda84edf0..47daa76b61d0 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
@@ -271,7 +271,7 @@ internal class SwipeAnimation<T : ContentKey>(
/** The offset animation that animates the offset once the user lifts their finger. */
private var offsetAnimation: Animatable<Float, AnimationVector1D>? by mutableStateOf(null)
- private val offsetAnimationRunnable = CompletableDeferred<(suspend () -> Unit)?>()
+ private val offsetAnimationRunnable = CompletableDeferred<suspend () -> Unit>()
val isUserInputOngoing: Boolean
get() = offsetAnimation == null
@@ -333,6 +333,7 @@ internal class SwipeAnimation<T : ContentKey>(
initialVelocity: Float,
targetContent: T,
spec: AnimationSpec<Float>? = null,
+ overscrollCompletable: CompletableDeferred<Unit>? = null,
): Float {
check(!isAnimatingOffset()) { "SwipeAnimation.animateOffset() can only be called once" }
@@ -391,7 +392,12 @@ internal class SwipeAnimation<T : ContentKey>(
// detail).
if (skipAnimation) {
// Unblock the job.
- offsetAnimationRunnable.complete(null)
+ offsetAnimationRunnable.complete {
+ // Wait for overscroll to finish so that the transition is removed from the STLState
+ // only after the overscroll is done, to avoid dropping frame right when the user
+ // lifts their finger and overscroll is animated to 0.
+ overscrollCompletable?.await()
+ }
return 0f
}
@@ -450,6 +456,11 @@ internal class SwipeAnimation<T : ContentKey>(
// The animation consumed the whole available velocity
velocityConsumed.complete(initialVelocity)
}
+
+ // Wait for overscroll to finish so that the transition is removed from the STLState
+ // only after the overscroll is done, to avoid dropping frame right when the user
+ // lifts their finger and overscroll is animated to 0.
+ overscrollCompletable?.await()
}
}