summaryrefslogtreecommitdiffstats
path: root/quickstep
diff options
context:
space:
mode:
authorJon Miranda <jonmiranda@google.com>2018-06-11 12:28:25 -0700
committerJon Miranda <jonmiranda@google.com>2018-06-20 16:35:19 -0700
commitcd57901ca460975205af9ba6cd5cd96a7225fc15 (patch)
tree37026375c464a971091b783d7f6beceec6655a80 /quickstep
parent730155ea0961555eee880b0bebebc0bb7c706eb3 (diff)
downloadandroid_packages_apps_Trebuchet-cd57901ca460975205af9ba6cd5cd96a7225fc15.tar.gz
android_packages_apps_Trebuchet-cd57901ca460975205af9ba6cd5cd96a7225fc15.tar.bz2
android_packages_apps_Trebuchet-cd57901ca460975205af9ba6cd5cd96a7225fc15.zip
Add stagger and "springs" to app closing transition.
The "spring" is actually three sequential animations: 1) a slide, 2) an oscillation, and 3) a settle. Bug: 109828964 Change-Id: I0a2c55f877446a6408952a1201636760283be57b
Diffstat (limited to 'quickstep')
-rw-r--r--quickstep/res/values/dimens.xml2
-rw-r--r--quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java112
2 files changed, 98 insertions, 16 deletions
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index afaad385d..0af2b2825 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -32,7 +32,7 @@
<!-- Launcher app transition -->
<dimen name="content_trans_y">50dp</dimen>
- <dimen name="workspace_trans_y">50dp</dimen>
+ <dimen name="springs_trans_y">-70dp</dimen>
<dimen name="closing_window_trans_y">115dp</dimen>
<dimen name="recents_empty_message_text_size">16sp</dimen>
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 14633afa5..4108cd290 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import static android.view.View.TRANSLATION_Y;
import static com.android.launcher3.BaseActivity.INVISIBLE_ALL;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS;
@@ -27,8 +28,10 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.OSCILLATE;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
import static com.android.quickstep.TaskUtils.findTaskViewToLaunch;
import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator;
@@ -115,12 +118,20 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
public static final int RECENTS_LAUNCH_DURATION = 336;
public static final int RECENTS_QUICKSCRUB_LAUNCH_DURATION = 300;
- private static final int LAUNCHER_RESUME_START_DELAY = 100;
+ private static final int LAUNCHER_RESUME_START_DELAY = 40;
private static final int CLOSING_TRANSITION_DURATION_MS = 250;
// Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down.
public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f;
+ private static final int APP_CLOSE_ROW_START_DELAY_MS = 8;
+
+ // The sum of [slide, oscillate, and settle] should be <= LAUNCHER_RESUME_TOTAL_DURATION.
+ private static final int LAUNCHER_RESUME_TOTAL_DURATION = 346;
+ private static final int SPRING_SLIDE_DURATION = 166;
+ private static final int SPRING_OSCILLATE_DURATION = 130;
+ private static final int SPRING_SETTLE_DURATION = 50;
+
private final Launcher mLauncher;
private final DragLayer mDragLayer;
private final AlphaProperty mDragLayerAlpha;
@@ -129,7 +140,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
private final boolean mIsRtl;
private final float mContentTransY;
- private final float mWorkspaceTransY;
+ private final float mStartSlideTransY;
+ private final float mEndSlideTransY;
private final float mClosingWindowTransY;
private DeviceProfile mDeviceProfile;
@@ -159,8 +171,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
Resources res = mLauncher.getResources();
mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y);
- mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y);
mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y);
+ mStartSlideTransY = res.getDimensionPixelSize(R.dimen.springs_trans_y);
+ mEndSlideTransY = -mStartSlideTransY * 0.1f;
mLauncher.addOnDeviceProfileChangeListener(this);
registerRemoteAnimations();
@@ -772,25 +785,49 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
});
} else {
AnimatorSet workspaceAnimator = new AnimatorSet();
+ workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
- mDragLayer.setTranslationY(-mWorkspaceTransY);;
- workspaceAnimator.play(ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y,
- -mWorkspaceTransY, 0));
+ ShortcutAndWidgetContainer currentPage = ((CellLayout) mLauncher.getWorkspace()
+ .getChildAt(mLauncher.getWorkspace().getCurrentPage()))
+ .getShortcutsAndWidgets();
- mDragLayerAlpha.setValue(0);
- workspaceAnimator.play(ObjectAnimator.ofFloat(
- mDragLayerAlpha, MultiValueAlpha.VALUE, 0, 1f));
+ // Set up springs on workspace items.
+ for (int i = currentPage.getChildCount() - 1; i >= 0; i--) {
+ View child = currentPage.getChildAt(i);
+ CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams());
+ addStaggeredAnimationForView(child, workspaceAnimator, lp.cellY + lp.cellVSpan);
+ }
- workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
- workspaceAnimator.setDuration(333);
- workspaceAnimator.setInterpolator(Interpolators.DEACCEL_1_7);
+ // Set up a spring for the shelf.
+ if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+ AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
+ float shiftRange = allAppsController.getShiftRange();
+ float slideStart = shiftRange / (shiftRange - mStartSlideTransY);
+ float oscillateStart = shiftRange / (shiftRange - mEndSlideTransY);
+ // Ensures a clean hand-off between slide and oscillate.
+ float slideEnd = Utilities.mapToRange(0, 0, 1f, oscillateStart, 1, OSCILLATE);
+
+ allAppsController.setProgress(slideStart);
+ Animator slideIn = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS,
+ slideStart, slideEnd);
+ slideIn.setDuration(SPRING_SLIDE_DURATION);
+ slideIn.setInterpolator(DEACCEL);
+
+ Animator oscillate = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS,
+ oscillateStart, 1f);
+ oscillate.setDuration(SPRING_OSCILLATE_DURATION);
+ oscillate.setInterpolator(OSCILLATE);
+
+ Animator settle = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, 1f);
+ settle.setDuration(SPRING_SETTLE_DURATION);
+ settle.setInterpolator(LINEAR);
+
+ workspaceAnimator.playSequentially(slideIn, oscillate, settle);
+ }
mDragLayer.getScrim().hideSysUiScrim(true);
-
// Pause page indicator animations as they lead to layer trashing.
mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
- mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-
workspaceAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -801,6 +838,51 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
}
+ /**
+ * Adds an alpha/trans animator for {@param v}, with a start delay based on the view's row.
+ *
+ * @param v View in a ShortcutAndWidgetContainer.
+ * @param row The bottom-most row that contains the view.
+ */
+ private void addStaggeredAnimationForView(View v, AnimatorSet outAnimator, int row) {
+ // Invert the rows, because we stagger starting from the bottom of the screen.
+ int invertedRow = LauncherAppState.getIDP(mLauncher).numRows - row + 1;
+ long startDelay = (long) (invertedRow * APP_CLOSE_ROW_START_DELAY_MS);
+
+ v.setAlpha(0);
+ ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 1f);
+ alpha.setInterpolator(LINEAR);
+ alpha.setDuration(SPRING_SLIDE_DURATION);
+ alpha.setStartDelay(startDelay);
+ outAnimator.play(alpha);
+
+ // Ensures a clean hand-off between slide and oscillate.
+ float slideEnd = Utilities.mapToRange(0, 0, 1f, mEndSlideTransY, 0, OSCILLATE);
+ v.setTranslationY(mStartSlideTransY);
+ ObjectAnimator slideIn = ObjectAnimator.ofFloat(v, TRANSLATION_Y, mStartSlideTransY,
+ slideEnd);
+ slideIn.setInterpolator(DEACCEL);
+ slideIn.setStartDelay(startDelay);
+ slideIn.setDuration(SPRING_SLIDE_DURATION);
+
+ ObjectAnimator oscillate = ObjectAnimator.ofFloat(v, TRANSLATION_Y, mEndSlideTransY, 0);
+ oscillate.setInterpolator(OSCILLATE);
+ oscillate.setDuration(SPRING_OSCILLATE_DURATION);
+
+ ObjectAnimator settle = ObjectAnimator.ofFloat(v, TRANSLATION_Y, 0);
+ settle.setInterpolator(LINEAR);
+ settle.setDuration(SPRING_SETTLE_DURATION);
+
+ outAnimator.playSequentially(slideIn, oscillate, settle);
+ outAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ v.setAlpha(1f);
+ v.setTranslationY(0);
+ }
+ });
+ }
+
private void resetContentView() {
mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
mDragLayerAlpha.setValue(1f);