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
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index 84e2304..732222a 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"/>
</com.android.launcher3.taskbar.TaskbarContainerView>
\ 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 7c54e2d..46e4506 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
@@ -50,6 +50,10 @@
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 @@
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 @@
mTaskbarCallbacks.updateTaskbarBackgroundAlpha(mTaskbarBackgroundAlpha.value);
updateVisibilityAlpha();
updateScale();
+ updateTranslationY();
}
private void updateVisibilityAlpha() {
@@ -120,6 +129,15 @@
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 ccf6b41..621bba7 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.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 @@
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 @@
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 @@
// 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 @@
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 d772964..c93de00 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
@@ -103,7 +103,7 @@
return new TaskbarAnimationControllerCallbacks() {
@Override
public void updateTaskbarBackgroundAlpha(float alpha) {
- mTaskbarViewInApp.setBackgroundAlpha(alpha);
+ mTaskbarContainerView.setTaskbarBackgroundAlpha(alpha);
}
@Override
@@ -117,6 +117,18 @@
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 AnimatedFloat getScaleTarget() {
return mTaskbarAnimationController.getTaskbarScaleForLauncherState();
}
+
+ @Override
+ public AnimatedFloat getTranslationYTarget() {
+ return mTaskbarAnimationController.getTaskbarTranslationYForLauncherState();
+ }
};
}
@@ -406,13 +423,15 @@
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 @@
* 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 @@
protected interface TaskbarStateHandlerCallbacks {
AnimatedFloat getAlphaTarget();
AnimatedFloat getScaleTarget();
+ AnimatedFloat getTranslationYTarget();
}
/**
@@ -464,6 +486,7 @@
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 9fc7d99..6ea51fa 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 @@
AnimatedFloat alphaTarget = mTaskbarCallbacks.getAlphaTarget();
AnimatedFloat scaleTarget = mTaskbarCallbacks.getScaleTarget();
+ AnimatedFloat translationYTarget = mTaskbarCallbacks.getTranslationYTarget();
boolean isTaskbarVisible = (state.getVisibleElements(mLauncher) & TASKBAR) != 0;
alphaTarget.updateValue(isTaskbarVisible ? 1f : 0f);
scaleTarget.updateValue(state.getTaskbarScale(mLauncher));
+ translationYTarget.updateValue(state.getTaskbarTranslationY(mLauncher));
}
@Override
@@ -68,9 +71,12 @@
AnimatedFloat alphaTarget = mTaskbarCallbacks.getAlphaTarget();
AnimatedFloat scaleTarget = mTaskbarCallbacks.getScaleTarget();
+ AnimatedFloat translationYTarget = mTaskbarCallbacks.getTranslationYTarget();
boolean isTaskbarVisible = (toState.getVisibleElements(mLauncher) & TASKBAR) != 0;
animation.setFloat(alphaTarget, AnimatedFloat.VALUE, isTaskbarVisible ? 1f : 0f, LINEAR);
animation.setFloat(scaleTarget, AnimatedFloat.VALUE, toState.getTaskbarScale(mLauncher),
LINEAR);
+ animation.setFloat(translationYTarget, AnimatedFloat.VALUE,
+ toState.getTaskbarTranslationY(mLauncher), ACCEL_DEACCEL);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index f254844..60a7add 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -24,7 +24,6 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.DragEvent;
import android.view.MotionEvent;
@@ -52,7 +51,6 @@
*/
public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconParent, Insettable {
- private final ColorDrawable mBackgroundDrawable;
private final int mIconTouchSize;
private final boolean mIsRtl;
private final int mTouchSlop;
@@ -97,7 +95,6 @@
super(context, attrs, defStyleAttr, defStyleRes);
Resources resources = getResources();
- mBackgroundDrawable = (ColorDrawable) getBackground();
mIconTouchSize = resources.getDimensionPixelSize(R.dimen.taskbar_icon_touch_size);
mIsRtl = Utilities.isRtl(resources);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
@@ -160,14 +157,6 @@
}
/**
- * Sets the alpha of the background color behind all the Taskbar contents.
- * @param alpha 0 is fully transparent, 1 is fully opaque.
- */
- public void setBackgroundAlpha(float alpha) {
- mBackgroundDrawable.setAlpha((int) (alpha * 255));
- }
-
- /**
* Inflates/binds the Hotseat views to show in the Taskbar given their ItemInfos.
*/
protected void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 6cdeb0f..30c07b0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -88,6 +88,11 @@
}
@Override
+ public float getTaskbarTranslationY(Launcher launcher) {
+ return 0f;
+ }
+
+ @Override
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
return new PageAlphaProvider(DEACCEL_2) {
@Override
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 2a903eb..c547d00 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -801,11 +801,9 @@
}
}
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 da41200..8496fd5 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -199,25 +199,38 @@
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.
*/
public void setIconsAlpha(float alpha) {
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 0c509a1..58df9c8 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -184,6 +184,10 @@
return launcher.getNormalTaskbarScale();
}
+ public float getTaskbarTranslationY(Launcher launcher) {
+ return -launcher.getHotseat().getTaskbarOffsetY();
+ }
+
public float getOverviewFullscreenProgress() {
return 0;
}