Loading quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java +11 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.quickstep.util; import static com.android.app.animation.Interpolators.LINEAR; import static com.android.app.animation.Interpolators.STANDARD; import android.view.animation.Interpolator; Loading @@ -38,6 +39,8 @@ public interface SplitAnimationTimings { int TABLET_APP_PAIR_LAUNCH_DURATION = 998; /** Total duration (ms) for launching an app pair from its icon on phones. */ int PHONE_APP_PAIR_LAUNCH_DURATION = 915; /** Total duration (ms) for fading out desktop tasks in split mode. */ int DESKTOP_FADE_OUT_DURATION = 200; // Initialize timing classes so they can be accessed statically SplitAnimationTimings TABLET_OVERVIEW_TO_SPLIT = new TabletOverviewToSplitTimings(); Loading Loading @@ -83,6 +86,10 @@ public interface SplitAnimationTimings { return (float) getStagedRectSlideEnd() / getDuration(); } default float getDesktopFadeSplitAnimationEndOffset() { return (float) DESKTOP_FADE_OUT_DURATION / getDuration(); } // DEFAULT VALUES: We define default values here so that SplitAnimationTimings can be used // flexibly in animation-running functions, e.g. a single function that handles 2 types of split // animations. The values are not intended to be used, and can safely be removed if refactoring Loading Loading @@ -124,5 +131,9 @@ public interface SplitAnimationTimings { default float getAppRevealEndOffset() { return 0; } default Interpolator getCellSplitInterpolator() { return LINEAR; } default Interpolator getIconFadeInterpolator() { return LINEAR; } default Interpolator getDesktopTaskScaleInterpolator() { return STANDARD; } } quickstep/src/com/android/quickstep/views/RecentsView.java +58 −15 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE; import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN; import static com.android.app.animation.Interpolators.FINAL_FRAME; import static com.android.app.animation.Interpolators.LINEAR; import static com.android.app.animation.Interpolators.OVERSHOOT_0_75; import static com.android.app.animation.Interpolators.EMPHASIZED; import static com.android.app.animation.Interpolators.clampToProgress; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU; Loading Loading @@ -3647,6 +3647,7 @@ public abstract class RecentsView< // Grid specific properties. boolean isFocusedTaskDismissed = false; boolean isStagingFocusedTask = false; boolean isSlidingTasks = false; TaskView nextFocusedTaskView = null; boolean nextFocusedTaskFromTop = false; float dismissedTaskWidth = 0; Loading Loading @@ -3702,6 +3703,7 @@ public abstract class RecentsView< scrollDiffPerPage = Math.abs(oldScroll[1] - oldScroll[0]); } isSlidingTasks = isStagingFocusedTask || areAllDesktopTasksDismissed; float dismissTranslationInterpolationEnd = 1; boolean closeGapBetweenClearAll = false; boolean isClearAllHidden = isClearAllHidden(); Loading Loading @@ -3842,14 +3844,14 @@ public abstract class RecentsView< AnimUtils.getDeviceOverviewToSplitTimings(mContainer.getDeviceProfile().isTablet); int distanceFromDismissedTask = 1; int stagingTranslation = 0; if (isStagingFocusedTask || areAllDesktopTasksDismissed) { int slidingTranslation = 0; if (isSlidingTasks) { int nextSnappedPage = isStagingFocusedTask ? indexOfChild(mUtils.getFirstSmallTaskView(getTaskViews())) : mUtils.getDesktopTaskViewCount(getTaskViews()); stagingTranslation = getPagedOrientationHandler().getPrimaryScroll(this) slidingTranslation = getPagedOrientationHandler().getPrimaryScroll(this) - getScrollForPage(nextSnappedPage); stagingTranslation += mIsRtl ? newClearAllShortTotalWidthTranslation slidingTranslation += mIsRtl ? newClearAllShortTotalWidthTranslation : -newClearAllShortTotalWidthTranslation; } mDismissPrimaryTranslations = new int[taskCount]; Loading Loading @@ -3877,12 +3879,12 @@ public abstract class RecentsView< // Animate task with index >= dismissed index and in the same row as the // dismissed index or next focused index. Offset successive task dismissal // durations for a staggered effect. int staggerColumn = isStagingFocusedTask int staggerColumn = isSlidingTasks ? (int) Math.ceil(distanceFromDismissedTask / 2f) : distanceFromDismissedTask; // Set timings based on if user is initiating splitscreen on the focused task, // or splitting/dismissing some other task. float animationStartProgress = isStagingFocusedTask float animationStartProgress = isSlidingTasks ? Utilities.boundToRange( splitTimings.getGridSlideStartOffset() + (splitTimings.getGridSlideStaggerOffset() Loading @@ -3893,7 +3895,7 @@ public abstract class RecentsView< INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * staggerColumn, 0f, dismissTranslationInterpolationEnd); float animationEndProgress = isStagingFocusedTask float animationEndProgress = isSlidingTasks ? Utilities.boundToRange( splitTimings.getGridSlideStartOffset() + (splitTimings.getGridSlideStaggerOffset() * staggerColumn) Loading @@ -3901,7 +3903,8 @@ public abstract class RecentsView< 0f, dismissTranslationInterpolationEnd) : dismissTranslationInterpolationEnd; Interpolator dismissInterpolator = isStagingFocusedTask ? OVERSHOOT_0_75 : LINEAR; Interpolator dismissInterpolator = isSlidingTasks ? EMPHASIZED : LINEAR; float primaryTranslation = 0; if (taskView == nextFocusedTaskView) { Loading @@ -3928,14 +3931,30 @@ public abstract class RecentsView< primaryTranslation += nextFocusedTaskView != null ? nextFocusedTaskWidth : dismissedTaskWidth; } primaryTranslation += mIsRtl ? stagingTranslation : -stagingTranslation; if (!(taskView instanceof DesktopTaskView)) { primaryTranslation += mIsRtl ? slidingTranslation : -slidingTranslation; } if (primaryTranslation != 0) { float finalTranslation = mIsRtl ? primaryTranslation : -primaryTranslation; anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(), finalTranslation, float startTranslation = 0; if (!(taskView instanceof DesktopTaskView) && slidingTranslation != 0) { startTranslation = isTaskViewVisible(taskView) ? 0 : finalTranslation + (mIsRtl ? -mLastComputedTaskSize.right : mLastComputedTaskSize.right); animationStartProgress = Utilities.boundToRange( animationStartProgress + splitTimings.getDesktopFadeSplitAnimationEndOffset(), 0f, dismissTranslationInterpolationEnd); } Animator dismissAnimator = ObjectAnimator.ofFloat(taskView, taskView.getPrimaryDismissTranslationProperty(), startTranslation, finalTranslation); dismissAnimator.setInterpolator( clampToProgress(dismissInterpolator, animationStartProgress, animationEndProgress)); anim.add(dismissAnimator); mDismissPrimaryTranslations[i] = (int) finalTranslation; distanceFromDismissedTask++; } Loading Loading @@ -5113,13 +5132,37 @@ public abstract class RecentsView< */ public void handleDesktopTaskInSplitSelectState(PendingAnimation builder, Interpolator deskTopFadeInterPolator) { SplitAnimationTimings timings = AnimUtils.getDeviceOverviewToSplitTimings( mContainer.getDeviceProfile().isTablet); if (enableLargeDesktopWindowingTile()) { for (TaskView taskView : getTaskViews()) { for (int i = 0; i < getTaskViewCount(); i++) { TaskView taskView = requireTaskViewAt(i); if (taskView instanceof DesktopTaskView) { // Correcting the animation for split mode since we hide DW in split. // Setting pivot to scale down from screen centre. if (i >= mCurrentPage - 1 && i <= mCurrentPage + 1) { float pivotX; if (i == mCurrentPage - 1) { pivotX = mIsRtl ? taskView.getWidth() / 2f - mPageSpacing - taskView.getWidth() : taskView.getWidth() / 2f + mPageSpacing + taskView.getWidth(); } else if (i == mCurrentPage) { pivotX = taskView.getWidth() / 2f; } else { pivotX = mIsRtl ? taskView.getWidth() + mPageSpacing + taskView.getWidth() : taskView.getWidth() - mPageSpacing - taskView.getWidth(); } taskView.setPivotX(pivotX); taskView.setPivotY(taskView.getHeight() / 2f); builder.add(ObjectAnimator .ofFloat(taskView, TaskView.DISMISS_SCALE, 0.95f), clampToProgress(timings.getDesktopTaskScaleInterpolator(), 0f, timings.getDesktopFadeSplitAnimationEndOffset())); } builder.addFloat(taskView.getSplitAlphaProperty(), MULTI_PROPERTY_VALUE, 1f, 0f, clampToProgress(deskTopFadeInterPolator, 0f, 0.1f)); clampToProgress(deskTopFadeInterPolator, 0f, timings.getDesktopFadeSplitAnimationEndOffset())); } } } Loading Loading
quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java +11 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.quickstep.util; import static com.android.app.animation.Interpolators.LINEAR; import static com.android.app.animation.Interpolators.STANDARD; import android.view.animation.Interpolator; Loading @@ -38,6 +39,8 @@ public interface SplitAnimationTimings { int TABLET_APP_PAIR_LAUNCH_DURATION = 998; /** Total duration (ms) for launching an app pair from its icon on phones. */ int PHONE_APP_PAIR_LAUNCH_DURATION = 915; /** Total duration (ms) for fading out desktop tasks in split mode. */ int DESKTOP_FADE_OUT_DURATION = 200; // Initialize timing classes so they can be accessed statically SplitAnimationTimings TABLET_OVERVIEW_TO_SPLIT = new TabletOverviewToSplitTimings(); Loading Loading @@ -83,6 +86,10 @@ public interface SplitAnimationTimings { return (float) getStagedRectSlideEnd() / getDuration(); } default float getDesktopFadeSplitAnimationEndOffset() { return (float) DESKTOP_FADE_OUT_DURATION / getDuration(); } // DEFAULT VALUES: We define default values here so that SplitAnimationTimings can be used // flexibly in animation-running functions, e.g. a single function that handles 2 types of split // animations. The values are not intended to be used, and can safely be removed if refactoring Loading Loading @@ -124,5 +131,9 @@ public interface SplitAnimationTimings { default float getAppRevealEndOffset() { return 0; } default Interpolator getCellSplitInterpolator() { return LINEAR; } default Interpolator getIconFadeInterpolator() { return LINEAR; } default Interpolator getDesktopTaskScaleInterpolator() { return STANDARD; } }
quickstep/src/com/android/quickstep/views/RecentsView.java +58 −15 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE; import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN; import static com.android.app.animation.Interpolators.FINAL_FRAME; import static com.android.app.animation.Interpolators.LINEAR; import static com.android.app.animation.Interpolators.OVERSHOOT_0_75; import static com.android.app.animation.Interpolators.EMPHASIZED; import static com.android.app.animation.Interpolators.clampToProgress; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU; Loading Loading @@ -3647,6 +3647,7 @@ public abstract class RecentsView< // Grid specific properties. boolean isFocusedTaskDismissed = false; boolean isStagingFocusedTask = false; boolean isSlidingTasks = false; TaskView nextFocusedTaskView = null; boolean nextFocusedTaskFromTop = false; float dismissedTaskWidth = 0; Loading Loading @@ -3702,6 +3703,7 @@ public abstract class RecentsView< scrollDiffPerPage = Math.abs(oldScroll[1] - oldScroll[0]); } isSlidingTasks = isStagingFocusedTask || areAllDesktopTasksDismissed; float dismissTranslationInterpolationEnd = 1; boolean closeGapBetweenClearAll = false; boolean isClearAllHidden = isClearAllHidden(); Loading Loading @@ -3842,14 +3844,14 @@ public abstract class RecentsView< AnimUtils.getDeviceOverviewToSplitTimings(mContainer.getDeviceProfile().isTablet); int distanceFromDismissedTask = 1; int stagingTranslation = 0; if (isStagingFocusedTask || areAllDesktopTasksDismissed) { int slidingTranslation = 0; if (isSlidingTasks) { int nextSnappedPage = isStagingFocusedTask ? indexOfChild(mUtils.getFirstSmallTaskView(getTaskViews())) : mUtils.getDesktopTaskViewCount(getTaskViews()); stagingTranslation = getPagedOrientationHandler().getPrimaryScroll(this) slidingTranslation = getPagedOrientationHandler().getPrimaryScroll(this) - getScrollForPage(nextSnappedPage); stagingTranslation += mIsRtl ? newClearAllShortTotalWidthTranslation slidingTranslation += mIsRtl ? newClearAllShortTotalWidthTranslation : -newClearAllShortTotalWidthTranslation; } mDismissPrimaryTranslations = new int[taskCount]; Loading Loading @@ -3877,12 +3879,12 @@ public abstract class RecentsView< // Animate task with index >= dismissed index and in the same row as the // dismissed index or next focused index. Offset successive task dismissal // durations for a staggered effect. int staggerColumn = isStagingFocusedTask int staggerColumn = isSlidingTasks ? (int) Math.ceil(distanceFromDismissedTask / 2f) : distanceFromDismissedTask; // Set timings based on if user is initiating splitscreen on the focused task, // or splitting/dismissing some other task. float animationStartProgress = isStagingFocusedTask float animationStartProgress = isSlidingTasks ? Utilities.boundToRange( splitTimings.getGridSlideStartOffset() + (splitTimings.getGridSlideStaggerOffset() Loading @@ -3893,7 +3895,7 @@ public abstract class RecentsView< INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * staggerColumn, 0f, dismissTranslationInterpolationEnd); float animationEndProgress = isStagingFocusedTask float animationEndProgress = isSlidingTasks ? Utilities.boundToRange( splitTimings.getGridSlideStartOffset() + (splitTimings.getGridSlideStaggerOffset() * staggerColumn) Loading @@ -3901,7 +3903,8 @@ public abstract class RecentsView< 0f, dismissTranslationInterpolationEnd) : dismissTranslationInterpolationEnd; Interpolator dismissInterpolator = isStagingFocusedTask ? OVERSHOOT_0_75 : LINEAR; Interpolator dismissInterpolator = isSlidingTasks ? EMPHASIZED : LINEAR; float primaryTranslation = 0; if (taskView == nextFocusedTaskView) { Loading @@ -3928,14 +3931,30 @@ public abstract class RecentsView< primaryTranslation += nextFocusedTaskView != null ? nextFocusedTaskWidth : dismissedTaskWidth; } primaryTranslation += mIsRtl ? stagingTranslation : -stagingTranslation; if (!(taskView instanceof DesktopTaskView)) { primaryTranslation += mIsRtl ? slidingTranslation : -slidingTranslation; } if (primaryTranslation != 0) { float finalTranslation = mIsRtl ? primaryTranslation : -primaryTranslation; anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(), finalTranslation, float startTranslation = 0; if (!(taskView instanceof DesktopTaskView) && slidingTranslation != 0) { startTranslation = isTaskViewVisible(taskView) ? 0 : finalTranslation + (mIsRtl ? -mLastComputedTaskSize.right : mLastComputedTaskSize.right); animationStartProgress = Utilities.boundToRange( animationStartProgress + splitTimings.getDesktopFadeSplitAnimationEndOffset(), 0f, dismissTranslationInterpolationEnd); } Animator dismissAnimator = ObjectAnimator.ofFloat(taskView, taskView.getPrimaryDismissTranslationProperty(), startTranslation, finalTranslation); dismissAnimator.setInterpolator( clampToProgress(dismissInterpolator, animationStartProgress, animationEndProgress)); anim.add(dismissAnimator); mDismissPrimaryTranslations[i] = (int) finalTranslation; distanceFromDismissedTask++; } Loading Loading @@ -5113,13 +5132,37 @@ public abstract class RecentsView< */ public void handleDesktopTaskInSplitSelectState(PendingAnimation builder, Interpolator deskTopFadeInterPolator) { SplitAnimationTimings timings = AnimUtils.getDeviceOverviewToSplitTimings( mContainer.getDeviceProfile().isTablet); if (enableLargeDesktopWindowingTile()) { for (TaskView taskView : getTaskViews()) { for (int i = 0; i < getTaskViewCount(); i++) { TaskView taskView = requireTaskViewAt(i); if (taskView instanceof DesktopTaskView) { // Correcting the animation for split mode since we hide DW in split. // Setting pivot to scale down from screen centre. if (i >= mCurrentPage - 1 && i <= mCurrentPage + 1) { float pivotX; if (i == mCurrentPage - 1) { pivotX = mIsRtl ? taskView.getWidth() / 2f - mPageSpacing - taskView.getWidth() : taskView.getWidth() / 2f + mPageSpacing + taskView.getWidth(); } else if (i == mCurrentPage) { pivotX = taskView.getWidth() / 2f; } else { pivotX = mIsRtl ? taskView.getWidth() + mPageSpacing + taskView.getWidth() : taskView.getWidth() - mPageSpacing - taskView.getWidth(); } taskView.setPivotX(pivotX); taskView.setPivotY(taskView.getHeight() / 2f); builder.add(ObjectAnimator .ofFloat(taskView, TaskView.DISMISS_SCALE, 0.95f), clampToProgress(timings.getDesktopTaskScaleInterpolator(), 0f, timings.getDesktopFadeSplitAnimationEndOffset())); } builder.addFloat(taskView.getSplitAlphaProperty(), MULTI_PROPERTY_VALUE, 1f, 0f, clampToProgress(deskTopFadeInterPolator, 0f, 0.1f)); clampToProgress(deskTopFadeInterPolator, 0f, timings.getDesktopFadeSplitAnimationEndOffset())); } } } Loading