From fd48b0c988eda8e801ab3417a2b117bd741e2963 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Mon, 31 Jan 2022 16:25:22 -0800 Subject: [PATCH] Add All Apps entry button to Taskbar. - Opens All Apps when clicked - Fades button in/out when transitioning b/w Hotseat & Taskbar Bug: 205803230 Test: manual ensures alpha gets reset properly clicking button opens all apps Change-Id: I1b96bae734aa9fd9308931d6312e3d65559d4284 --- .../taskbar/TaskbarAllAppsViewController.java | 4 -- .../launcher3/taskbar/TaskbarView.java | 25 ++++++++++ .../taskbar/TaskbarViewController.java | 34 ++++++++++++-- res/drawable/ic_all_apps_button.xml | 43 +++++++++++++++++ .../launcher3/InvariantDeviceProfile.java | 2 +- .../launcher3/views/AllAppsButton.java | 47 +++++++++++++++++++ 6 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 res/drawable/ic_all_apps_button.xml create mode 100644 src/com/android/launcher3/views/AllAppsButton.java diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsViewController.java index 0b53cc2c84..62125feae6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsViewController.java @@ -15,7 +15,6 @@ */ package com.android.launcher3.taskbar; -import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; @@ -41,9 +40,6 @@ public final class TaskbarAllAppsViewController { mAppsView.setOnIconLongClickListener( controllers.taskbarDragController::startDragOnLongClick); - - // TODO(b/205803230): Remove once entry point button is implemented. - mContext.getDragLayer().findViewById(R.id.taskbar_view).setOnClickListener(v -> show()); } /** Binds the current {@link AppInfo} instances to the {@link TaskbarAllAppsContainerView}. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index c8d9fca947..fddd1ed6fb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -22,6 +22,7 @@ import android.graphics.Rect; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.widget.FrameLayout; import androidx.annotation.LayoutRes; @@ -31,6 +32,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.BubbleTextView; import com.android.launcher3.Insettable; import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; @@ -38,6 +40,7 @@ import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.uioverrides.ApiWrapper; import com.android.launcher3.util.LauncherBindableItemsContainer; import com.android.launcher3.views.ActivityContext; +import com.android.launcher3.views.AllAppsButton; /** * Hosts the Taskbar content such as Hotseat and Recent Apps. Drawn on top of other apps. @@ -64,6 +67,9 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar // Only non-null when the corresponding Folder is open. private @Nullable FolderIcon mLeaveBehindFolderIcon; + // Only non-null when device supports having an All Apps button. + private @Nullable AllAppsButton mAllAppsButton; + public TaskbarView(@NonNull Context context) { this(context, null); } @@ -94,6 +100,13 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar // Needed to draw folder leave-behind when opening one. setWillNotDraw(false); + + if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) { + mAllAppsButton = new AllAppsButton(context); + mAllAppsButton.setLayoutParams( + new ViewGroup.LayoutParams(mIconTouchSize, mIconTouchSize)); + mAllAppsButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding); + } } protected void init(TaskbarViewController.TaskbarViewCallbacks callbacks) { @@ -102,6 +115,10 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar mIconLongClickListener = mControllerCallbacks.getIconOnLongClickListener(); setOnLongClickListener(mControllerCallbacks.getBackgroundOnLongClickListener()); + + if (mAllAppsButton != null) { + mAllAppsButton.setOnClickListener(mControllerCallbacks.getAllAppsButtonClickListener()); + } } private void removeAndRecycle(View view) { @@ -121,6 +138,10 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar int nextViewIndex = 0; int numViewsAnimated = 0; + if (mAllAppsButton != null) { + removeView(mAllAppsButton); + } + for (int i = 0; i < hotseatItemInfos.length; i++) { ItemInfo hotseatItemInfo = hotseatItemInfos[i]; if (hotseatItemInfo == null) { @@ -191,6 +212,10 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar while (nextViewIndex < getChildCount()) { removeAndRecycle(getChildAt(nextViewIndex)); } + + if (mAllAppsButton != null) { + addView(mAllAppsButton); + } } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 0508994eac..778040dbc1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -22,6 +22,7 @@ import static com.android.quickstep.AnimatedFloat.VALUE; import android.graphics.Rect; import android.util.FloatProperty; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; @@ -33,6 +34,7 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.LauncherBindableItemsContainer; @@ -45,6 +47,9 @@ import java.io.PrintWriter; * Handles properties/data collection, then passes the results to TaskbarView to render. */ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbarController { + + private static final String TAG = TaskbarViewController.class.getSimpleName(); + private static final Runnable NO_OP = () -> { }; public static final int ALPHA_INDEX_HOME = 0; @@ -225,14 +230,29 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar int count = mTaskbarView.getChildCount(); for (int i = 0; i < count; i++) { View child = mTaskbarView.getChildAt(i); - ItemInfo info = (ItemInfo) child.getTag(); - setter.setFloat(child, SCALE_PROPERTY, scaleUp, LINEAR); + + int positionInHotseat = -1; + if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get() && i == count - 1) { + // Note that there is no All Apps button in the hotseat, this position is only used + // as its convenient for animation purposes. + positionInHotseat = mActivity.getDeviceProfile().inv.numShownHotseatIcons; + + setter.setViewAlpha(child, 0, LINEAR); + } else if (child.getTag() instanceof ItemInfo) { + positionInHotseat = ((ItemInfo) child.getTag()).screenId; + } else { + Log.w(TAG, "Unsupported view found in createIconAlignmentController, v=" + child); + continue; + } + + float hotseatIconCenter = hotseatPadding.left + + (hotseatCellSize + borderSpacing) * positionInHotseat + + hotseatCellSize / 2; float childCenter = (child.getLeft() + child.getRight()) / 2; - float hotseatIconCenter = hotseatPadding.left - + (hotseatCellSize + borderSpacing) * info.screenId - + hotseatCellSize / 2; setter.setFloat(child, ICON_TRANSLATE_X, hotseatIconCenter - childCenter, LINEAR); + + setter.setFloat(child, SCALE_PROPERTY, scaleUp, LINEAR); } AnimatorPlaybackController controller = setter.createPlaybackController(); @@ -279,6 +299,10 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar return mActivity.getItemOnClickListener(); } + public View.OnClickListener getAllAppsButtonClickListener() { + return v -> mControllers.taskbarAllAppsViewController.show(); + } + public View.OnLongClickListener getIconOnLongClickListener() { return mControllers.taskbarDragController::startDragOnLongClick; } diff --git a/res/drawable/ic_all_apps_button.xml b/res/drawable/ic_all_apps_button.xml new file mode 100644 index 0000000000..52b919bd27 --- /dev/null +++ b/res/drawable/ic_all_apps_button.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 0b168a5242..a381787804 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -135,7 +135,7 @@ public class InvariantDeviceProfile { /** * Number of icons inside the hotseat area. */ - protected int numShownHotseatIcons; + public int numShownHotseatIcons; /** * Number of icons inside the hotseat area that is stored in the database. This is greater than diff --git a/src/com/android/launcher3/views/AllAppsButton.java b/src/com/android/launcher3/views/AllAppsButton.java new file mode 100644 index 0000000000..f502d46db7 --- /dev/null +++ b/src/com/android/launcher3/views/AllAppsButton.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.views; + +import android.content.Context; +import android.graphics.Bitmap; +import android.util.AttributeSet; + +import com.android.launcher3.BubbleTextView; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.R; +import com.android.launcher3.icons.FastBitmapDrawable; + +/** + * Button in Taskbar that opens All Apps. + */ +public class AllAppsButton extends BubbleTextView { + + public AllAppsButton(Context context) { + this(context, null); + } + + public AllAppsButton(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public AllAppsButton(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + Bitmap bitmap = LauncherAppState.getInstance(context).getIconCache().getIconFactory() + .createScaledBitmapWithShadow(context.getDrawable(R.drawable.ic_all_apps_button)); + setIcon(new FastBitmapDrawable(bitmap)); + } +}