From 81f8175ab12c37eb81a78e2ed27570fd7ddc0d88 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 7 Apr 2021 11:06:40 -0700 Subject: [PATCH] Move taskbar to be closer to QSB - Offset taskbar to be halfway between QSB and bottom of the screen. - Add taskbar translationY state property to animate when going between launcher and an app. - Draw the taskbar background in TaskbarContainerView instead of TaskbarView so it stays pinned to the bottom as TaskbarView translates up. If we want to have a background behind the taskbar on home, this should move back to TaskbarView so that the drawing can be shared by mTaskbarViewOnHome. Test: visually on home screen, translates when entering and exiting an app Bug: 182981881 Bug: 171917176 Change-Id: I44f8b2c770074f7f015dcccbc2befd3453811193 --- quickstep/res/layout/taskbar.xml | 1 - .../taskbar/TaskbarAnimationController.java | 18 ++++++++ .../taskbar/TaskbarContainerView.java | 24 +++++++++++ .../launcher3/taskbar/TaskbarController.java | 43 ++++++++++++++----- .../taskbar/TaskbarStateHandler.java | 6 +++ .../launcher3/taskbar/TaskbarView.java | 11 ----- .../uioverrides/states/OverviewState.java | 5 +++ .../android/quickstep/AbsSwipeUpHandler.java | 8 ++-- src/com/android/launcher3/Hotseat.java | 29 +++++++++---- src/com/android/launcher3/LauncherState.java | 4 ++ 10 files changed, 114 insertions(+), 35 deletions(-) diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml index 84e23043b0..732222ade8 100644 --- a/quickstep/res/layout/taskbar.xml +++ b/quickstep/res/layout/taskbar.xml @@ -24,7 +24,6 @@ android:id="@+id/taskbar_view" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@color/taskbar_background" android:gravity="center"/> \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java index 7c54e2d6b9..46e4506f1f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java @@ -50,6 +50,10 @@ public class TaskbarAnimationController { private final AnimatedFloat mTaskbarScaleForLauncherState = new AnimatedFloat( this::updateScale); + // TranslationY. + private final AnimatedFloat mTaskbarTranslationYForLauncherState = new AnimatedFloat( + this::updateTranslationY); + public TaskbarAnimationController(BaseQuickstepLauncher launcher, TaskbarController.TaskbarAnimationControllerCallbacks taskbarCallbacks) { mLauncher = launcher; @@ -81,6 +85,10 @@ public class TaskbarAnimationController { return mTaskbarScaleForLauncherState; } + protected AnimatedFloat getTaskbarTranslationYForLauncherState() { + return mTaskbarTranslationYForLauncherState; + } + protected Animator createAnimToBackgroundAlpha(float toAlpha, long duration) { return mTaskbarBackgroundAlpha.animateToValue(mTaskbarBackgroundAlpha.value, toAlpha) .setDuration(duration); @@ -95,6 +103,7 @@ public class TaskbarAnimationController { mTaskbarCallbacks.updateTaskbarBackgroundAlpha(mTaskbarBackgroundAlpha.value); updateVisibilityAlpha(); updateScale(); + updateTranslationY(); } private void updateVisibilityAlpha() { @@ -120,6 +129,15 @@ public class TaskbarAnimationController { mTaskbarCallbacks.updateTaskbarScale(scale); } + private void updateTranslationY() { + // We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the + // assumption being that Taskbar should always be at translationY 0f regardless of the + // current LauncherState if Launcher is paused. + float translationY = mTaskbarTranslationYForLauncherState.value; + translationY = Utilities.mapRange(mTaskbarBackgroundAlpha.value, translationY, 0f); + mTaskbarCallbacks.updateTaskbarTranslationY(translationY); + } + private void setNavBarButtonAlpha(float navBarAlpha) { SystemUiProxy.INSTANCE.get(mLauncher).setNavBarButtonAlpha(navBarAlpha, false); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java index ccf6b41e5d..621bba7e85 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java @@ -19,6 +19,8 @@ import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsI import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION; import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; @@ -38,6 +40,7 @@ public class TaskbarContainerView extends BaseDragLayer private final int[] mTempLoc = new int[2]; private final int mFolderMargin; + private final Paint mTaskbarBackgroundPaint; // Initialized in TaskbarController constructor. private TaskbarController.TaskbarContainerViewCallbacks mControllerCallbacks; @@ -63,6 +66,8 @@ public class TaskbarContainerView extends BaseDragLayer int defStyleAttr, int defStyleRes) { super(context, attrs, 1 /* alphaChannelCount */); mFolderMargin = getResources().getDimensionPixelSize(R.dimen.taskbar_folder_margin); + mTaskbarBackgroundPaint = new Paint(); + mTaskbarBackgroundPaint.setColor(getResources().getColor(R.color.taskbar_background)); } protected void construct(TaskbarController.TaskbarContainerViewCallbacks callbacks) { @@ -97,11 +102,14 @@ public class TaskbarContainerView extends BaseDragLayer // mTaskbarView is, since its position never changes and insets rather than overlays. int[] loc = mTempLoc; float scale = mTaskbarView.getScaleX(); + float translationY = mTaskbarView.getTranslationY(); mTaskbarView.setScaleX(1); mTaskbarView.setScaleY(1); + mTaskbarView.setTranslationY(0); mTaskbarView.getLocationInWindow(loc); mTaskbarView.setScaleX(scale); mTaskbarView.setScaleY(scale); + mTaskbarView.setTranslationY(translationY); insetsInfo.contentInsets.left = loc[0]; insetsInfo.contentInsets.top = loc[1]; insetsInfo.contentInsets.right = getWidth() - (loc[0] + mTaskbarView.getWidth()); @@ -153,4 +161,20 @@ public class TaskbarContainerView extends BaseDragLayer protected TaskbarActivityContext getTaskbarActivityContext() { return mActivity; } + + @Override + protected void dispatchDraw(Canvas canvas) { + canvas.drawRect(0, canvas.getHeight() - mTaskbarView.getHeight(), canvas.getWidth(), + canvas.getHeight(), mTaskbarBackgroundPaint); + super.dispatchDraw(canvas); + } + + /** + * Sets the alpha of the background color behind all the Taskbar contents. + * @param alpha 0 is fully transparent, 1 is fully opaque. + */ + protected void setTaskbarBackgroundAlpha(float alpha) { + mTaskbarBackgroundPaint.setAlpha((int) (alpha * 255)); + invalidate(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java index d772964ecf..c93de00f4f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java @@ -103,7 +103,7 @@ public class TaskbarController { return new TaskbarAnimationControllerCallbacks() { @Override public void updateTaskbarBackgroundAlpha(float alpha) { - mTaskbarViewInApp.setBackgroundAlpha(alpha); + mTaskbarContainerView.setTaskbarBackgroundAlpha(alpha); } @Override @@ -117,6 +117,18 @@ public class TaskbarController { mTaskbarViewInApp.setScaleX(scale); mTaskbarViewInApp.setScaleY(scale); } + + @Override + public void updateTaskbarTranslationY(float translationY) { + if (translationY < 0) { + // Resize to accommodate the max translation we'll reach. + setTaskbarWindowHeight(mTaskbarSize.y + + mLauncher.getHotseat().getTaskbarOffsetY()); + } else { + setTaskbarWindowHeight(mTaskbarSize.y); + } + mTaskbarViewInApp.setTranslationY(translationY); + } }; } @@ -240,6 +252,11 @@ public class TaskbarController { public AnimatedFloat getScaleTarget() { return mTaskbarAnimationController.getTaskbarScaleForLauncherState(); } + + @Override + public AnimatedFloat getTranslationYTarget() { + return mTaskbarAnimationController.getTaskbarTranslationYForLauncherState(); + } }; } @@ -406,13 +423,15 @@ public class TaskbarController { Rect hotseatBounds = new Rect(); DeviceProfile grid = mLauncher.getDeviceProfile(); int hotseatHeight = grid.workspacePadding.bottom + grid.taskbarSize; - int hotseatTopDiff = hotseatHeight - grid.taskbarSize; + int taskbarOffset = mLauncher.getHotseat().getTaskbarOffsetY(); + int hotseatTopDiff = hotseatHeight - grid.taskbarSize - taskbarOffset; + int hotseatBottomDiff = taskbarOffset; mTaskbarViewOnHome.getHotseatBounds().roundOut(hotseatBounds); mLauncher.getHotseat().setPadding(hotseatBounds.left, hotseatBounds.top + hotseatTopDiff, mTaskbarViewOnHome.getWidth() - hotseatBounds.right, - mTaskbarViewOnHome.getHeight() - hotseatBounds.bottom); + mTaskbarViewOnHome.getHeight() - hotseatBounds.bottom + hotseatBottomDiff); } private void setWhichTaskbarViewIsVisible(@Nullable TaskbarView visibleTaskbar) { @@ -438,13 +457,15 @@ public class TaskbarController { * Updates the TaskbarContainer to MATCH_PARENT vs original Taskbar size. */ private void setTaskbarWindowFullscreen(boolean fullscreen) { - if (fullscreen) { - mWindowLayoutParams.width = MATCH_PARENT; - mWindowLayoutParams.height = MATCH_PARENT; - } else { - mWindowLayoutParams.width = mTaskbarSize.x; - mWindowLayoutParams.height = mTaskbarSize.y; - } + setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : mTaskbarSize.y); + } + + /** + * Updates the TaskbarContainer height (pass mTaskbarSize.y to reset). + */ + private void setTaskbarWindowHeight(int height) { + mWindowLayoutParams.width = mTaskbarSize.x; + mWindowLayoutParams.height = height; mWindowManager.updateViewLayout(mTaskbarContainerView, mWindowLayoutParams); } @@ -454,6 +475,7 @@ public class TaskbarController { protected interface TaskbarStateHandlerCallbacks { AnimatedFloat getAlphaTarget(); AnimatedFloat getScaleTarget(); + AnimatedFloat getTranslationYTarget(); } /** @@ -464,6 +486,7 @@ public class TaskbarController { void updateTaskbarBackgroundAlpha(float alpha); void updateTaskbarVisibilityAlpha(float alpha); void updateTaskbarScale(float scale); + void updateTaskbarTranslationY(float translationY); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java index 9fc7d995a7..6ea51fa5eb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java @@ -16,6 +16,7 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.LauncherState.TASKBAR; +import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; import androidx.annotation.Nullable; @@ -54,9 +55,11 @@ public class TaskbarStateHandler implements StateManager.StateHandler, } } if (mParallelRunningAnim != null) { - if (cancel) { - mParallelRunningAnim.cancel(); - } else { - mParallelRunningAnim.end(); - } + // Unlike the above animation, the parallel animation won't have anything to take up + // the work if it's canceled, so just end it instead. + mParallelRunningAnim.end(); } } diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index da41200040..8496fd5d9c 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -199,24 +199,37 @@ public class Hotseat extends CellLayout implements Insettable { int left = (r - l - qsbWidth) / 2; int right = left + qsbWidth; - DeviceProfile dp = mActivity.getDeviceProfile(); - int freeSpace = dp.isTaskbarPresent - ? dp.workspacePadding.bottom - : dp.hotseatBarSizePx - dp.hotseatCellHeightPx - mQsbHeight; - int bottom = b - t - - (int) (freeSpace * QSB_CENTER_FACTOR) - - (dp.isTaskbarPresent ? dp.taskbarSize : dp.getInsets().bottom); + int bottom = b - t - getQsbOffsetY(); int top = bottom - mQsbHeight; mQsb.layout(left, top, right, bottom); int taskbarWidth = mTaskbarView.getMeasuredWidth(); left = (r - l - taskbarWidth) / 2; right = left + taskbarWidth; - bottom = b - t; + bottom = b - t - getTaskbarOffsetY(); top = bottom - mTaskbarViewHeight; mTaskbarView.layout(left, top, right, bottom); } + /** + * Returns the number of pixels the QSB is translated from the bottom of the screen. + */ + private int getQsbOffsetY() { + DeviceProfile dp = mActivity.getDeviceProfile(); + int freeSpace = dp.isTaskbarPresent + ? dp.workspacePadding.bottom + : dp.hotseatBarSizePx - dp.hotseatCellHeightPx - mQsbHeight; + return (int) (freeSpace * QSB_CENTER_FACTOR) + + (dp.isTaskbarPresent ? dp.taskbarSize : dp.getInsets().bottom); + } + + /** + * Returns the number of pixels the taskbar is translated from the bottom of the screen. + */ + public int getTaskbarOffsetY() { + return (getQsbOffsetY() - mTaskbarViewHeight) / 2; + } + /** * Sets the alpha value of just our ShortcutAndWidgetContainer. */ diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 0c509a112a..58df9c8f64 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -184,6 +184,10 @@ public abstract class LauncherState implements BaseState { return launcher.getNormalTaskbarScale(); } + public float getTaskbarTranslationY(Launcher launcher) { + return -launcher.getHotseat().getTaskbarOffsetY(); + } + public float getOverviewFullscreenProgress() { return 0; }