Run dismiss immediately if no neighbors exist.

Previously was still relying on spring driver to end, even if driving no neighbors.

Update live tile before canceling animation to bring task off screen, or else it may still show at the top of the screen.

Fix: 405364868
Test: Manual
Flag: com.android.launcher3.enable_expressive_dismiss_task_motion
Change-Id: Ic9a1b4ba9aaf1ec3830e49bf15573388a6d7a2ad
This commit is contained in:
Pat Manning
2025-03-25 14:35:35 +00:00
parent 6db50866de
commit 8216005fd0
2 changed files with 26 additions and 21 deletions
@@ -68,15 +68,16 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) {
.setSpring(createExpressiveDismissSpringForce())
.setStartVelocity(startVelocity)
.addUpdateListener { animation, value, _ ->
if (isDismissing && abs(value) >= abs(dismissLength)) {
animation.cancel()
} else if (draggedTaskView.isRunningTask && recentsView.enableDrawingLiveTile) {
if (draggedTaskView.isRunningTask && recentsView.enableDrawingLiveTile) {
recentsView.runActionOnRemoteHandles { remoteTargetHandle ->
remoteTargetHandle.taskViewSimulator.taskSecondaryTranslation.value =
taskDismissFloatProperty.getValue(draggedTaskView)
}
recentsView.redrawLiveTile()
}
if (isDismissing && abs(value) >= abs(dismissLength)) {
animation.cancel()
}
}
.addEndListener { _, _, _, _ ->
if (isDismissing) {
@@ -444,7 +445,17 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) {
}
}
if (tasksToReflow.isNotEmpty()) {
// Start animations and remove the dismissed task at the end, dismiss immediately if no
// neighboring tasks exist.
val runGridEndAnimationAndRelayout = { dismissDuration: Int ->
recentsView.expressiveDismissTaskView(dismissedTaskView, onEndRunnable, dismissDuration)
}
val runImmediately = tasksToReflow.isEmpty()
if (runImmediately) {
// Play the same haptic as when neighbors spring into place.
MSDLPlayerWrapper.INSTANCE.get(recentsView.context)?.playToken(MSDLToken.CANCEL)
runGridEndAnimationAndRelayout(DISMISS_IMMEDIATE_DURATION)
} else {
addNeighborSettlingSpringAnimations(
dismissedTaskView,
springAnimationDriver,
@@ -453,22 +464,13 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) {
isSpringDirectionVertical = false,
minVelocity = 0f,
)
} else {
springAnimationDriver.addEndListener { _, _, _, _ ->
// Play the same haptic as when neighbors spring into place.
MSDLPlayerWrapper.INSTANCE.get(recentsView.context)?.playToken(MSDLToken.CANCEL)
springAnimationDriver.apply {
addEndListener { _, _, _, _ ->
runGridEndAnimationAndRelayout(DISMISS_DEFAULT_DURATION)
}
animateToFinalPosition(dismissedTaskGap)
}
}
// Start animations and remove the dismissed task at the end, dismiss immediately if no
// neighboring tasks exist.
val runGridEndAnimationAndRelayout = {
recentsView.expressiveDismissTaskView(dismissedTaskView, onEndRunnable)
}
springAnimationDriver?.apply {
addEndListener { _, _, _, _ -> runGridEndAnimationAndRelayout() }
animateToFinalPosition(dismissedTaskGap)
} ?: runGridEndAnimationAndRelayout()
}
private fun getDismissedTaskGapForReflow(dismissedTaskView: TaskView): Float {
@@ -557,5 +559,7 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) {
// The additional damping to apply to tasks further from the dismissed task.
private const val ADDITIONAL_DISMISS_DAMPING_RATIO = 0.15f
private const val RECENTS_SCALE_SPRING_MULTIPLIER = 1000f
private const val DISMISS_DEFAULT_DURATION = 300
private const val DISMISS_IMMEDIATE_DURATION = 10
}
}
@@ -4718,10 +4718,11 @@ public abstract class RecentsView<
runDismissAnimation(pa);
}
protected void expressiveDismissTaskView(TaskView taskView, Function0<Unit> onEndRunnable) {
PendingAnimation pa = new PendingAnimation(DISMISS_TASK_DURATION);
protected void expressiveDismissTaskView(TaskView taskView, Function0<Unit> onEndRunnable,
int dismissDuration) {
PendingAnimation pa = new PendingAnimation(dismissDuration);
createTaskDismissAnimation(pa, taskView, false /* animateTaskView */, true /* removeTask */,
DISMISS_TASK_DURATION, false /* dismissingForSplitSelection*/,
dismissDuration, false /* dismissingForSplitSelection*/,
true /* isExpressiveDismiss */);
pa.addEndListener((success) -> onEndRunnable.invoke());
runDismissAnimation(pa);