Loading quickstep/res/values/dimens.xml +5 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,11 @@ <dimen name="overview_grid_focus_vertical_margin">90dp</dimen> <dimen name="split_placeholder_size">110dp</dimen> <!-- These speeds are in dp/s --> <dimen name="max_task_dismiss_drag_velocity">2.25dp</dimen> <dimen name="default_task_dismiss_drag_velocity">1.75dp</dimen> <dimen name="default_task_dismiss_drag_velocity_grid">0.75dp</dimen> <dimen name="recents_page_spacing">16dp</dimen> <dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen> Loading quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +30 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.view.animation.Interpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; Loading @@ -50,6 +51,10 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity> extends AnimatorListenerAdapter implements TouchController, SingleAxisSwipeDetector.Listener { private static final float ANIMATION_PROGRESS_FRACTION_MIDPOINT = 0.5f; private static final long MIN_TASK_DISMISS_ANIMATION_DURATION = 300; private static final long MAX_TASK_DISMISS_ANIMATION_DURATION = 600; protected final T mActivity; private final SingleAxisSwipeDetector mDetector; private final RecentsView mRecentsView; Loading Loading @@ -277,14 +282,32 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity> } else { mFlingBlockCheck.onEvent(); } mCurrentAnimation.setPlayFraction(Utilities.boundToRange( totalDisplacement * mProgressMultiplier, 0, 1)); // Once halfway through task dismissal interpolation, switch from reversible dragging-task // animation to playing the remaining task translation animations if (mCurrentAnimation.getProgressFraction() < ANIMATION_PROGRESS_FRACTION_MIDPOINT) { // Halve the value as we are animating the drag across the full length for only the // first half of the progress mCurrentAnimation.setPlayFraction( Utilities.boundToRange(totalDisplacement * mProgressMultiplier / 2, 0, 1)); } else { float dragVelocity = -mTaskBeingDragged.getResources().getDimension( mRecentsView.showAsGrid() ? R.dimen.default_task_dismiss_drag_velocity_grid : R.dimen.default_task_dismiss_drag_velocity); onDragEnd(dragVelocity); return true; } return true; } @Override public void onDragEnd(float velocity) { // Limit velocity, as very large scalar values make animations play too quickly float maxTaskDismissDragVelocity = mTaskBeingDragged.getResources().getDimension( R.dimen.max_task_dismiss_drag_velocity); velocity = Utilities.boundToRange(velocity, -maxTaskDismissDragVelocity, maxTaskDismissDragVelocity); boolean fling = mDetector.isFling(velocity); final boolean goingToEnd; boolean blockedFling = fling && mFlingBlockCheck.isBlocked(); Loading @@ -305,6 +328,11 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity> if (blockedFling && !goingToEnd) { animationDuration *= LauncherAnimUtils.blockedFlingDurationFactor(velocity); } // Due to very high or low velocity dismissals, animation durations can be inconsistently // long or short. Bound the duration for animation of task translations for a more // standardized feel. animationDuration = Utilities.boundToRange(animationDuration, MIN_TASK_DISMISS_ANIMATION_DURATION, MAX_TASK_DISMISS_ANIMATION_DURATION); mCurrentAnimation.setEndAction(this::clearState); mCurrentAnimation.startWithVelocity(mActivity, goingToEnd, Loading quickstep/src/com/android/quickstep/views/RecentsView.java +51 −52 Original line number Diff line number Diff line Loading @@ -32,11 +32,12 @@ import static com.android.launcher3.Utilities.mapToRange; import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.Utilities.squaredTouchSlop; import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.ACCEL_0_5; import static com.android.launcher3.anim.Interpolators.ACCEL_0_75; import static com.android.launcher3.anim.Interpolators.ACCEL_2; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN; Loading Loading @@ -336,6 +337,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T // OverScroll constants private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270; private static final int DISMISS_TASK_DURATION = 300; private static final int ADDITION_TASK_DURATION = 200; private static final float INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.55f; private static final float ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.05f; protected final RecentsOrientedState mOrientationState; protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy; protected RecentsAnimationController mRecentsAnimationController; Loading @@ -358,10 +364,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T private final List<OnScrollChangedListener> mScrollListeners = new ArrayList<>(); private float mFullscreenScale; private static final int DISMISS_TASK_DURATION = 300; private static final int DISMISS_TASK_TRANSLATION_DURATION = 200; private static final int ADDITIONAL_DISMISS_TASK_TRANSLATION_DURATION = 75; private static final int ADDITION_TASK_DURATION = 200; // The threshold at which we update the SystemUI flags when animating from the task into the app public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f; Loading Loading @@ -1886,21 +1888,18 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T * This method is used when no task dismissal has occurred. */ private void updateGridProperties() { updateGridProperties(null, -1); updateGridProperties(false); } /** * Updates TaskView and ClearAllButton scaling and translation required to turn into grid * layout. * This method only calculates the potential position and depends on {@link #setGridProgress} to * apply the actual scaling and translation. This adds task translation animations in the case * of task dismissals: e.g. when dismissedTask is not null. * apply the actual scaling and translation. * * @param dismissedTask the TaskView dismissed, possibly null * @param dismissedIndex the index at which the dismissedTask was prior to dismissal, if no * dismissal occurred, this is unused * @param isTaskDismissal indicates if update was called due to task dismissal */ private void updateGridProperties(TaskView dismissedTask, int dismissedIndex) { private void updateGridProperties(boolean isTaskDismissal) { int taskCount = getTaskViewCount(); if (taskCount == 0) { return; Loading Loading @@ -1940,10 +1939,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T int snappedPage = getNextPage(); TaskView snappedTaskView = getTaskViewAtByAbsoluteIndex(snappedPage); boolean isTaskDismissal = dismissedTask != null; float dismissedTaskWidth = isTaskDismissal ? dismissedTask.getLayoutParams().width + mPageSpacing : 0; if (!isTaskDismissal) { mTopRowIdSet.clear(); } Loading Loading @@ -2039,34 +2034,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T snappedTaskGridTranslationX = gridTranslations[snappedPage - mTaskViewStartIndex]; } // Animate task dismissTranslationX for tasks with index >= dismissed index and in the // same row as the dismissed index, or if the dismissed task was the focused task. Offset // successive task dismissal durations for a staggered effect. ArrayList<Animator> gridTranslationAnimators = new ArrayList<>(); boolean isFocusedTaskDismissed = isTaskDismissal && dismissedTask.getTask().key.id == mFocusedTaskId; for (int i = 0; i < taskCount; i++) { TaskView taskView = getTaskViewAt(i); if (isFocusedTaskDismissed || (i >= dismissedIndex && isSameGridRow(dismissedTask, taskView))) { Animator taskDismissAnimator = ObjectAnimator.ofFloat(taskView, taskView.getPrimaryDismissTranslationProperty(), mIsRtl ? -dismissedTaskWidth : dismissedTaskWidth, 0f); int additionalTranslationDuration = i >= dismissedIndex ? (ADDITIONAL_DISMISS_TASK_TRANSLATION_DURATION * ( (i - dismissedIndex) / 2)) : 0; taskDismissAnimator.setDuration( DISMISS_TASK_TRANSLATION_DURATION + additionalTranslationDuration); gridTranslationAnimators.add(taskDismissAnimator); } taskView.setGridTranslationX(gridTranslations[i] - snappedTaskGridTranslationX); taskView.getPrimaryNonFullscreenTranslationProperty().set(taskView, snappedTaskFullscreenScrollAdjustment); taskView.getSecondaryNonFullscreenTranslationProperty().set(taskView, 0f); } AnimatorSet gridTranslationAnimatorSet = new AnimatorSet(); gridTranslationAnimatorSet.playTogether(gridTranslationAnimators); gridTranslationAnimatorSet.start(); // Use the accumulated translation of the row containing the last task. float clearAllAccumulatedTranslation = topSet.contains(taskCount - 1) Loading Loading @@ -2210,7 +2184,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T PendingAnimation anim) { // Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's // alpha is set to 0 so that it can be recycled in the view pool properly anim.setFloat(taskView, VIEW_ALPHA, 0, ACCEL_2); anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(ACCEL, 0, 0.5f)); SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController(); ResourceProvider rp = DynamicResource.provider(mActivity); Loading Loading @@ -2246,8 +2220,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T throw new IllegalStateException("Invalid split task translation: " + dir); } } // Double translation distance so dismissal drag is the full height, as we only animate // the drag for the first half of the progress. anim.add(ObjectAnimator.ofFloat(taskView, dismissingTaskViewTranslate, positiveNegativeFactor * translateDistance).setDuration(duration), LINEAR, sp); positiveNegativeFactor * translateDistance * 2).setDuration(duration), LINEAR, sp); if (LIVE_TILE.get() && taskView.isRunningTask()) { anim.addOnFrameCallback(() -> { Loading Loading @@ -2283,6 +2259,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } int draggedIndex = indexOfChild(taskView); boolean isFocusedTaskDismissed = taskView.getTask().key.id == mFocusedTaskId; if (isFocusedTaskDismissed && showAsGrid()) { anim.setFloat(mActionsView, VIEW_ALPHA, 0, clampToProgress(ACCEL_0_5, 0, 0.5f)); } float dismissedTaskWidth = taskView.getLayoutParams().width + mPageSpacing; boolean needsCurveUpdates = false; for (int i = 0; i < count; i++) { View child = getChildAt(i); Loading @@ -2291,7 +2272,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T addDismissedTaskAnimations(taskView, duration, anim); } } else if (!showAsGrid()) { // For grid layout, don't animate other tasks when dismissing in grid for now. // Compute scroll offsets from task dismissal for animation. // If we just take newScroll - oldScroll, everything to the right of dragged task // translates to the left. We need to offset this in some cases: // - In RTL, add page offset to all pages, since we want pages to move to the right Loading @@ -2318,15 +2299,31 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T ? ((TaskView) child).getPrimaryDismissTranslationProperty() : mOrientationHandler.getPrimaryViewTranslate(); ResourceProvider rp = DynamicResource.provider(mActivity); SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_END) .setDampingRatio( rp.getFloat(R.dimen.dismiss_task_trans_x_damping_ratio)) .setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_x_stiffness)); anim.add(ObjectAnimator.ofFloat(child, translationProperty, scrollDiff) .setDuration(duration), ACCEL, sp); float additionalDismissDuration = ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs( i - draggedIndex); anim.setFloat(child, translationProperty, scrollDiff, clampToProgress(LINEAR, Utilities.boundToRange(INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + additionalDismissDuration, 0f, 1f), 1)); needsCurveUpdates = true; } } else if (child instanceof TaskView) { // Animate task with index >= dismissed index and in the same row as the // dismissed index, or if the dismissed task was the focused task. Offset // successive task dismissal durations for a staggered effect. if (isFocusedTaskDismissed || (i >= draggedIndex && isSameGridRow((TaskView) child, taskView))) { FloatProperty translationProperty = ((TaskView) child).getPrimaryDismissTranslationProperty(); float additionalDismissDuration = ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs( i - draggedIndex); anim.setFloat(child, translationProperty, !mIsRtl ? -dismissedTaskWidth : dismissedTaskWidth, clampToProgress(LINEAR, Utilities.boundToRange( INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + additionalDismissDuration, 0f, 1f), 1)); } } } Loading Loading @@ -2364,6 +2361,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } } // Reset task translations as they may have updated via animations in // createTaskDismissAnimation resetTaskVisuals(); int pageToSnapTo = mCurrentPage; // Snap to start if focused task was dismissed, as after quick switch it could // be at any page but the focused task always displays at the start. Loading @@ -2381,7 +2382,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } else { snapToPageImmediately(pageToSnapTo); // Grid got messed up, reapply. updateGridProperties(taskView, draggedIndex - mTaskViewStartIndex); updateGridProperties(true); if (showAsGrid() && getFocusedTaskView() == null && mActionsView.getVisibilityAlpha().getValue() == 1) { animateActionsViewOut(); Loading @@ -2391,9 +2392,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T // immediately available. onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom()); } if (!showAsGrid()) { resetTaskVisuals(); } onDismissAnimationEnds(); mPendingAnimation = null; } Loading Loading @@ -3721,7 +3719,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return mColorTint; } private boolean showAsGrid() { /** Returns {@code true} if the overview tasks are displayed as a grid. */ public boolean showAsGrid() { return mOverviewGridEnabled || (mCurrentGestureEndTarget != null && mSizeStrategy.stateFromGestureEndTarget( mCurrentGestureEndTarget).displayOverviewTasksAsGrid(mActivity.getDeviceProfile())); Loading src/com/android/launcher3/anim/Interpolators.java +8 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ public class Interpolators { public static final Interpolator LINEAR = new LinearInterpolator(); public static final Interpolator ACCEL = new AccelerateInterpolator(); public static final Interpolator ACCEL_0_5 = new AccelerateInterpolator(0.5f); public static final Interpolator ACCEL_0_75 = new AccelerateInterpolator(0.75f); public static final Interpolator ACCEL_1_5 = new AccelerateInterpolator(1.5f); public static final Interpolator ACCEL_2 = new AccelerateInterpolator(2); Loading Loading @@ -149,11 +150,15 @@ public class Interpolators { */ public static Interpolator clampToProgress(Interpolator interpolator, float lowerBound, float upperBound) { if (upperBound <= lowerBound) { throw new IllegalArgumentException(String.format( "lowerBound (%f) must be less than upperBound (%f)", lowerBound, upperBound)); if (upperBound < lowerBound) { throw new IllegalArgumentException( String.format("upperBound (%f) must be greater than lowerBound (%f)", upperBound, lowerBound)); } return t -> { if (t == lowerBound && t == upperBound) { return t == 0f ? 0 : 1; } if (t < lowerBound) { return 0; } Loading Loading
quickstep/res/values/dimens.xml +5 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,11 @@ <dimen name="overview_grid_focus_vertical_margin">90dp</dimen> <dimen name="split_placeholder_size">110dp</dimen> <!-- These speeds are in dp/s --> <dimen name="max_task_dismiss_drag_velocity">2.25dp</dimen> <dimen name="default_task_dismiss_drag_velocity">1.75dp</dimen> <dimen name="default_task_dismiss_drag_velocity_grid">0.75dp</dimen> <dimen name="recents_page_spacing">16dp</dimen> <dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen> Loading
quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +30 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.view.animation.Interpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; Loading @@ -50,6 +51,10 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity> extends AnimatorListenerAdapter implements TouchController, SingleAxisSwipeDetector.Listener { private static final float ANIMATION_PROGRESS_FRACTION_MIDPOINT = 0.5f; private static final long MIN_TASK_DISMISS_ANIMATION_DURATION = 300; private static final long MAX_TASK_DISMISS_ANIMATION_DURATION = 600; protected final T mActivity; private final SingleAxisSwipeDetector mDetector; private final RecentsView mRecentsView; Loading Loading @@ -277,14 +282,32 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity> } else { mFlingBlockCheck.onEvent(); } mCurrentAnimation.setPlayFraction(Utilities.boundToRange( totalDisplacement * mProgressMultiplier, 0, 1)); // Once halfway through task dismissal interpolation, switch from reversible dragging-task // animation to playing the remaining task translation animations if (mCurrentAnimation.getProgressFraction() < ANIMATION_PROGRESS_FRACTION_MIDPOINT) { // Halve the value as we are animating the drag across the full length for only the // first half of the progress mCurrentAnimation.setPlayFraction( Utilities.boundToRange(totalDisplacement * mProgressMultiplier / 2, 0, 1)); } else { float dragVelocity = -mTaskBeingDragged.getResources().getDimension( mRecentsView.showAsGrid() ? R.dimen.default_task_dismiss_drag_velocity_grid : R.dimen.default_task_dismiss_drag_velocity); onDragEnd(dragVelocity); return true; } return true; } @Override public void onDragEnd(float velocity) { // Limit velocity, as very large scalar values make animations play too quickly float maxTaskDismissDragVelocity = mTaskBeingDragged.getResources().getDimension( R.dimen.max_task_dismiss_drag_velocity); velocity = Utilities.boundToRange(velocity, -maxTaskDismissDragVelocity, maxTaskDismissDragVelocity); boolean fling = mDetector.isFling(velocity); final boolean goingToEnd; boolean blockedFling = fling && mFlingBlockCheck.isBlocked(); Loading @@ -305,6 +328,11 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity> if (blockedFling && !goingToEnd) { animationDuration *= LauncherAnimUtils.blockedFlingDurationFactor(velocity); } // Due to very high or low velocity dismissals, animation durations can be inconsistently // long or short. Bound the duration for animation of task translations for a more // standardized feel. animationDuration = Utilities.boundToRange(animationDuration, MIN_TASK_DISMISS_ANIMATION_DURATION, MAX_TASK_DISMISS_ANIMATION_DURATION); mCurrentAnimation.setEndAction(this::clearState); mCurrentAnimation.startWithVelocity(mActivity, goingToEnd, Loading
quickstep/src/com/android/quickstep/views/RecentsView.java +51 −52 Original line number Diff line number Diff line Loading @@ -32,11 +32,12 @@ import static com.android.launcher3.Utilities.mapToRange; import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.Utilities.squaredTouchSlop; import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.ACCEL_0_5; import static com.android.launcher3.anim.Interpolators.ACCEL_0_75; import static com.android.launcher3.anim.Interpolators.ACCEL_2; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN; Loading Loading @@ -336,6 +337,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T // OverScroll constants private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270; private static final int DISMISS_TASK_DURATION = 300; private static final int ADDITION_TASK_DURATION = 200; private static final float INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.55f; private static final float ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.05f; protected final RecentsOrientedState mOrientationState; protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy; protected RecentsAnimationController mRecentsAnimationController; Loading @@ -358,10 +364,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T private final List<OnScrollChangedListener> mScrollListeners = new ArrayList<>(); private float mFullscreenScale; private static final int DISMISS_TASK_DURATION = 300; private static final int DISMISS_TASK_TRANSLATION_DURATION = 200; private static final int ADDITIONAL_DISMISS_TASK_TRANSLATION_DURATION = 75; private static final int ADDITION_TASK_DURATION = 200; // The threshold at which we update the SystemUI flags when animating from the task into the app public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f; Loading Loading @@ -1886,21 +1888,18 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T * This method is used when no task dismissal has occurred. */ private void updateGridProperties() { updateGridProperties(null, -1); updateGridProperties(false); } /** * Updates TaskView and ClearAllButton scaling and translation required to turn into grid * layout. * This method only calculates the potential position and depends on {@link #setGridProgress} to * apply the actual scaling and translation. This adds task translation animations in the case * of task dismissals: e.g. when dismissedTask is not null. * apply the actual scaling and translation. * * @param dismissedTask the TaskView dismissed, possibly null * @param dismissedIndex the index at which the dismissedTask was prior to dismissal, if no * dismissal occurred, this is unused * @param isTaskDismissal indicates if update was called due to task dismissal */ private void updateGridProperties(TaskView dismissedTask, int dismissedIndex) { private void updateGridProperties(boolean isTaskDismissal) { int taskCount = getTaskViewCount(); if (taskCount == 0) { return; Loading Loading @@ -1940,10 +1939,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T int snappedPage = getNextPage(); TaskView snappedTaskView = getTaskViewAtByAbsoluteIndex(snappedPage); boolean isTaskDismissal = dismissedTask != null; float dismissedTaskWidth = isTaskDismissal ? dismissedTask.getLayoutParams().width + mPageSpacing : 0; if (!isTaskDismissal) { mTopRowIdSet.clear(); } Loading Loading @@ -2039,34 +2034,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T snappedTaskGridTranslationX = gridTranslations[snappedPage - mTaskViewStartIndex]; } // Animate task dismissTranslationX for tasks with index >= dismissed index and in the // same row as the dismissed index, or if the dismissed task was the focused task. Offset // successive task dismissal durations for a staggered effect. ArrayList<Animator> gridTranslationAnimators = new ArrayList<>(); boolean isFocusedTaskDismissed = isTaskDismissal && dismissedTask.getTask().key.id == mFocusedTaskId; for (int i = 0; i < taskCount; i++) { TaskView taskView = getTaskViewAt(i); if (isFocusedTaskDismissed || (i >= dismissedIndex && isSameGridRow(dismissedTask, taskView))) { Animator taskDismissAnimator = ObjectAnimator.ofFloat(taskView, taskView.getPrimaryDismissTranslationProperty(), mIsRtl ? -dismissedTaskWidth : dismissedTaskWidth, 0f); int additionalTranslationDuration = i >= dismissedIndex ? (ADDITIONAL_DISMISS_TASK_TRANSLATION_DURATION * ( (i - dismissedIndex) / 2)) : 0; taskDismissAnimator.setDuration( DISMISS_TASK_TRANSLATION_DURATION + additionalTranslationDuration); gridTranslationAnimators.add(taskDismissAnimator); } taskView.setGridTranslationX(gridTranslations[i] - snappedTaskGridTranslationX); taskView.getPrimaryNonFullscreenTranslationProperty().set(taskView, snappedTaskFullscreenScrollAdjustment); taskView.getSecondaryNonFullscreenTranslationProperty().set(taskView, 0f); } AnimatorSet gridTranslationAnimatorSet = new AnimatorSet(); gridTranslationAnimatorSet.playTogether(gridTranslationAnimators); gridTranslationAnimatorSet.start(); // Use the accumulated translation of the row containing the last task. float clearAllAccumulatedTranslation = topSet.contains(taskCount - 1) Loading Loading @@ -2210,7 +2184,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T PendingAnimation anim) { // Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's // alpha is set to 0 so that it can be recycled in the view pool properly anim.setFloat(taskView, VIEW_ALPHA, 0, ACCEL_2); anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(ACCEL, 0, 0.5f)); SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController(); ResourceProvider rp = DynamicResource.provider(mActivity); Loading Loading @@ -2246,8 +2220,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T throw new IllegalStateException("Invalid split task translation: " + dir); } } // Double translation distance so dismissal drag is the full height, as we only animate // the drag for the first half of the progress. anim.add(ObjectAnimator.ofFloat(taskView, dismissingTaskViewTranslate, positiveNegativeFactor * translateDistance).setDuration(duration), LINEAR, sp); positiveNegativeFactor * translateDistance * 2).setDuration(duration), LINEAR, sp); if (LIVE_TILE.get() && taskView.isRunningTask()) { anim.addOnFrameCallback(() -> { Loading Loading @@ -2283,6 +2259,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } int draggedIndex = indexOfChild(taskView); boolean isFocusedTaskDismissed = taskView.getTask().key.id == mFocusedTaskId; if (isFocusedTaskDismissed && showAsGrid()) { anim.setFloat(mActionsView, VIEW_ALPHA, 0, clampToProgress(ACCEL_0_5, 0, 0.5f)); } float dismissedTaskWidth = taskView.getLayoutParams().width + mPageSpacing; boolean needsCurveUpdates = false; for (int i = 0; i < count; i++) { View child = getChildAt(i); Loading @@ -2291,7 +2272,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T addDismissedTaskAnimations(taskView, duration, anim); } } else if (!showAsGrid()) { // For grid layout, don't animate other tasks when dismissing in grid for now. // Compute scroll offsets from task dismissal for animation. // If we just take newScroll - oldScroll, everything to the right of dragged task // translates to the left. We need to offset this in some cases: // - In RTL, add page offset to all pages, since we want pages to move to the right Loading @@ -2318,15 +2299,31 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T ? ((TaskView) child).getPrimaryDismissTranslationProperty() : mOrientationHandler.getPrimaryViewTranslate(); ResourceProvider rp = DynamicResource.provider(mActivity); SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_END) .setDampingRatio( rp.getFloat(R.dimen.dismiss_task_trans_x_damping_ratio)) .setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_x_stiffness)); anim.add(ObjectAnimator.ofFloat(child, translationProperty, scrollDiff) .setDuration(duration), ACCEL, sp); float additionalDismissDuration = ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs( i - draggedIndex); anim.setFloat(child, translationProperty, scrollDiff, clampToProgress(LINEAR, Utilities.boundToRange(INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + additionalDismissDuration, 0f, 1f), 1)); needsCurveUpdates = true; } } else if (child instanceof TaskView) { // Animate task with index >= dismissed index and in the same row as the // dismissed index, or if the dismissed task was the focused task. Offset // successive task dismissal durations for a staggered effect. if (isFocusedTaskDismissed || (i >= draggedIndex && isSameGridRow((TaskView) child, taskView))) { FloatProperty translationProperty = ((TaskView) child).getPrimaryDismissTranslationProperty(); float additionalDismissDuration = ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs( i - draggedIndex); anim.setFloat(child, translationProperty, !mIsRtl ? -dismissedTaskWidth : dismissedTaskWidth, clampToProgress(LINEAR, Utilities.boundToRange( INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + additionalDismissDuration, 0f, 1f), 1)); } } } Loading Loading @@ -2364,6 +2361,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } } // Reset task translations as they may have updated via animations in // createTaskDismissAnimation resetTaskVisuals(); int pageToSnapTo = mCurrentPage; // Snap to start if focused task was dismissed, as after quick switch it could // be at any page but the focused task always displays at the start. Loading @@ -2381,7 +2382,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } else { snapToPageImmediately(pageToSnapTo); // Grid got messed up, reapply. updateGridProperties(taskView, draggedIndex - mTaskViewStartIndex); updateGridProperties(true); if (showAsGrid() && getFocusedTaskView() == null && mActionsView.getVisibilityAlpha().getValue() == 1) { animateActionsViewOut(); Loading @@ -2391,9 +2392,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T // immediately available. onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom()); } if (!showAsGrid()) { resetTaskVisuals(); } onDismissAnimationEnds(); mPendingAnimation = null; } Loading Loading @@ -3721,7 +3719,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return mColorTint; } private boolean showAsGrid() { /** Returns {@code true} if the overview tasks are displayed as a grid. */ public boolean showAsGrid() { return mOverviewGridEnabled || (mCurrentGestureEndTarget != null && mSizeStrategy.stateFromGestureEndTarget( mCurrentGestureEndTarget).displayOverviewTasksAsGrid(mActivity.getDeviceProfile())); Loading
src/com/android/launcher3/anim/Interpolators.java +8 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ public class Interpolators { public static final Interpolator LINEAR = new LinearInterpolator(); public static final Interpolator ACCEL = new AccelerateInterpolator(); public static final Interpolator ACCEL_0_5 = new AccelerateInterpolator(0.5f); public static final Interpolator ACCEL_0_75 = new AccelerateInterpolator(0.75f); public static final Interpolator ACCEL_1_5 = new AccelerateInterpolator(1.5f); public static final Interpolator ACCEL_2 = new AccelerateInterpolator(2); Loading Loading @@ -149,11 +150,15 @@ public class Interpolators { */ public static Interpolator clampToProgress(Interpolator interpolator, float lowerBound, float upperBound) { if (upperBound <= lowerBound) { throw new IllegalArgumentException(String.format( "lowerBound (%f) must be less than upperBound (%f)", lowerBound, upperBound)); if (upperBound < lowerBound) { throw new IllegalArgumentException( String.format("upperBound (%f) must be greater than lowerBound (%f)", upperBound, lowerBound)); } return t -> { if (t == lowerBound && t == upperBound) { return t == 0f ? 0 : 1; } if (t < lowerBound) { return 0; } Loading