Scale recents on drag of tasks during dismiss.
Fix: 389083567 Test: TaplTestsQuickstep#testDismissCancel Flag: com.android.launcher3.enable_expressive_dismiss_task_motion Change-Id: Ibeb0a742cdfb4392c920deb64dd5bd4f221a9564
This commit is contained in:
+56
@@ -19,6 +19,7 @@ import android.content.Context
|
||||
import android.view.MotionEvent
|
||||
import androidx.dynamicanimation.animation.SpringAnimation
|
||||
import com.android.app.animation.Interpolators.DECELERATE
|
||||
import com.android.app.animation.Interpolators.LINEAR
|
||||
import com.android.launcher3.AbstractFloatingView
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.Utilities.EDGE_NAV_BAR
|
||||
@@ -29,6 +30,7 @@ import com.android.launcher3.touch.SingleAxisSwipeDetector
|
||||
import com.android.launcher3.util.MSDLPlayerWrapper
|
||||
import com.android.launcher3.util.TouchController
|
||||
import com.android.quickstep.views.RecentsView
|
||||
import com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY
|
||||
import com.android.quickstep.views.RecentsViewContainer
|
||||
import com.android.quickstep.views.TaskView
|
||||
import com.google.android.msdl.data.model.MSDLToken
|
||||
@@ -57,6 +59,7 @@ CONTAINER : RecentsViewContainer {
|
||||
private var verticalFactor: Int = 0
|
||||
private var hasDismissThresholdHapticRun = false
|
||||
private var initialDisplacement: Float = 0f
|
||||
private var recentsScaleAnimation: SpringAnimation? = null
|
||||
|
||||
private fun canInterceptTouch(ev: MotionEvent): Boolean =
|
||||
when {
|
||||
@@ -98,6 +101,7 @@ CONTAINER : RecentsViewContainer {
|
||||
|
||||
private fun onActionDown(ev: MotionEvent): Boolean {
|
||||
springAnimation?.cancel()
|
||||
recentsScaleAnimation?.cancel()
|
||||
if (!canInterceptTouch(ev)) {
|
||||
return false
|
||||
}
|
||||
@@ -162,6 +166,8 @@ CONTAINER : RecentsViewContainer {
|
||||
}
|
||||
recentsView.redrawLiveTile()
|
||||
}
|
||||
val dismissFraction = displacement / (dismissLength * verticalFactor).toFloat()
|
||||
RECENTS_SCALE_PROPERTY.setValue(recentsView, getRecentsScale(dismissFraction))
|
||||
playDismissThresholdHaptic(displacement)
|
||||
return true
|
||||
}
|
||||
@@ -216,6 +222,10 @@ CONTAINER : RecentsViewContainer {
|
||||
if (isDismissing) (dismissLength * verticalFactor).toFloat() else 0f
|
||||
)
|
||||
}
|
||||
recentsScaleAnimation =
|
||||
recentsView.animateRecentsScale(RECENTS_SCALE_DEFAULT).addEndListener { _, _, _, _ ->
|
||||
recentsScaleAnimation = null
|
||||
}
|
||||
}
|
||||
|
||||
// Returns if the current task being dragged is towards "positive" (e.g. dismissal).
|
||||
@@ -230,8 +240,54 @@ CONTAINER : RecentsViewContainer {
|
||||
springAnimation = null
|
||||
}
|
||||
|
||||
private fun getRecentsScale(dismissFraction: Float): Float {
|
||||
return when {
|
||||
// Do not scale recents when dragging below origin.
|
||||
dismissFraction <= 0 -> {
|
||||
RECENTS_SCALE_DEFAULT
|
||||
}
|
||||
// Initially scale recents as the drag begins, up to the first threshold.
|
||||
dismissFraction < RECENTS_SCALE_FIRST_THRESHOLD_FRACTION -> {
|
||||
mapToRange(
|
||||
dismissFraction,
|
||||
0f,
|
||||
RECENTS_SCALE_FIRST_THRESHOLD_FRACTION,
|
||||
RECENTS_SCALE_DEFAULT,
|
||||
RECENTS_SCALE_ON_DISMISS_CANCEL,
|
||||
LINEAR,
|
||||
)
|
||||
}
|
||||
// Keep scale consistent until dragging to the dismiss threshold.
|
||||
dismissFraction < RECENTS_SCALE_DISMISS_THRESHOLD_FRACTION -> {
|
||||
RECENTS_SCALE_ON_DISMISS_CANCEL
|
||||
}
|
||||
// Scale beyond the dismiss threshold again, to indicate dismiss will occur on release.
|
||||
dismissFraction < RECENTS_SCALE_SECOND_THRESHOLD_FRACTION -> {
|
||||
mapToRange(
|
||||
dismissFraction,
|
||||
RECENTS_SCALE_DISMISS_THRESHOLD_FRACTION,
|
||||
RECENTS_SCALE_SECOND_THRESHOLD_FRACTION,
|
||||
RECENTS_SCALE_ON_DISMISS_CANCEL,
|
||||
RECENTS_SCALE_ON_DISMISS_SUCCESS,
|
||||
LINEAR,
|
||||
)
|
||||
}
|
||||
// Keep scale beyond the dismiss threshold scaling consistent.
|
||||
else -> {
|
||||
RECENTS_SCALE_ON_DISMISS_SUCCESS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val DISMISS_THRESHOLD_FRACTION = 0.5f
|
||||
private const val DISMISS_THRESHOLD_HAPTIC_RANGE = 10f
|
||||
|
||||
private const val RECENTS_SCALE_ON_DISMISS_CANCEL = 0.9875f
|
||||
private const val RECENTS_SCALE_ON_DISMISS_SUCCESS = 0.975f
|
||||
private const val RECENTS_SCALE_DEFAULT = 1f
|
||||
private const val RECENTS_SCALE_FIRST_THRESHOLD_FRACTION = 0.2f
|
||||
private const val RECENTS_SCALE_DISMISS_THRESHOLD_FRACTION = 0.5f
|
||||
private const val RECENTS_SCALE_SECOND_THRESHOLD_FRACTION = 0.575f
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6950,6 +6950,13 @@ public abstract class RecentsView<
|
||||
isDismissing, detector, dismissLength, onEndRunnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates RecentsView's scale to the provided value, using spring animations.
|
||||
*/
|
||||
public SpringAnimation animateRecentsScale(float scale) {
|
||||
return mUtils.animateRecentsScale(scale);
|
||||
}
|
||||
|
||||
public interface TaskLaunchListener {
|
||||
void onTaskLaunched();
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.android.launcher3.util.MSDLPlayerWrapper
|
||||
import com.android.quickstep.util.GroupTask
|
||||
import com.android.quickstep.util.TaskGridNavHelper
|
||||
import com.android.quickstep.util.isExternalDisplay
|
||||
import com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY
|
||||
import com.android.quickstep.views.RecentsView.RUNNING_TASK_ATTACH_ALPHA
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData
|
||||
import com.google.android.msdl.data.model.MSDLToken
|
||||
@@ -362,7 +363,6 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) {
|
||||
addNeighboringSpringAnimationsForDismissCancel(
|
||||
draggedTaskView,
|
||||
draggedTaskViewSpringAnimation,
|
||||
recentsView.pageCount,
|
||||
)
|
||||
}
|
||||
return draggedTaskViewSpringAnimation
|
||||
@@ -371,7 +371,6 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) {
|
||||
private fun addNeighboringSpringAnimationsForDismissCancel(
|
||||
draggedTaskView: TaskView,
|
||||
draggedTaskViewSpringAnimation: SpringAnimation,
|
||||
taskCount: Int,
|
||||
) {
|
||||
// Empty spring animation exists for conditional start, and to drive neighboring springs.
|
||||
val neighborsToSettle =
|
||||
@@ -559,10 +558,39 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Animates RecentsView's scale to the provided value, using spring animations. */
|
||||
fun animateRecentsScale(scale: Float): SpringAnimation {
|
||||
val resourceProvider = DynamicResource.provider(recentsView.mContainer)
|
||||
val dampingRatio = resourceProvider.getFloat(R.dimen.swipe_up_rect_scale_damping_ratio)
|
||||
val stiffness = resourceProvider.getFloat(R.dimen.swipe_up_rect_scale_stiffness)
|
||||
|
||||
// Spring which sets the Recents scale on update. This is needed, as the SpringAnimation
|
||||
// struggles to animate small values like changing recents scale from 0.9 to 1. So
|
||||
// we animate over a larger range (e.g. 900 to 1000) and convert back to the required value.
|
||||
// (This is instead of converting RECENTS_SCALE_PROPERTY to a FloatPropertyCompat and
|
||||
// animating it directly via springs.)
|
||||
val initialRecentsScaleSpringValue =
|
||||
RECENTS_SCALE_SPRING_MULTIPLIER * RECENTS_SCALE_PROPERTY.get(recentsView)
|
||||
return SpringAnimation(FloatValueHolder(initialRecentsScaleSpringValue))
|
||||
.setSpring(
|
||||
SpringForce(initialRecentsScaleSpringValue)
|
||||
.setDampingRatio(dampingRatio)
|
||||
.setStiffness(stiffness)
|
||||
)
|
||||
.addUpdateListener { _, value, _ ->
|
||||
RECENTS_SCALE_PROPERTY.setValue(
|
||||
recentsView,
|
||||
value / RECENTS_SCALE_SPRING_MULTIPLIER,
|
||||
)
|
||||
}
|
||||
.apply { animateToFinalPosition(RECENTS_SCALE_SPRING_MULTIPLIER * scale) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TEMP_RECT = Rect()
|
||||
|
||||
// The additional damping to apply to tasks further from the dismissed task.
|
||||
const val ADDITIONAL_DISMISS_DAMPING_RATIO = 0.15f
|
||||
private const val ADDITIONAL_DISMISS_DAMPING_RATIO = 0.15f
|
||||
private const val RECENTS_SCALE_SPRING_MULTIPLIER = 1000f
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user