adding the new Material U App Shortcut Popup design
Bug: 247880037
Test: tested manually
Change-Id: I66c291df54dfc2a76fc974082a19091deb167f73
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 41632f7..8097fd7 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -3211,7 +3211,7 @@
}
@Override
- public boolean shouldUseColorExtractionForPopup() {
+ public boolean canUseMultipleShadesForPopup() {
return getTopOpenViewWithType(this, TYPE_FOLDER) == null
&& getStateManager().getState() != LauncherState.ALL_APPS;
}
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 9a745ab..c23ea8a 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.anim.Interpolators.ACCELERATED_EASE;
import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -116,7 +117,7 @@
private final String mIterateChildrenTag;
- private final int[] mColorIds;
+ protected final int[] mColorIds;
public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
@@ -125,8 +126,8 @@
mActivityContext = ActivityContext.lookupContext(context);
mIsRtl = Utilities.isRtl(getResources());
- int backgroundColor = Themes.getAttrColor(context, R.attr.popupColorPrimary);
- mArrowColor = backgroundColor;
+ int popupPrimaryColor = Themes.getAttrColor(context, R.attr.popupColorPrimary);
+ mArrowColor = popupPrimaryColor;
mElevation = getResources().getDimension(R.dimen.deep_shortcuts_elevation);
// Initialize arrow view
@@ -143,18 +144,18 @@
int smallerRadius = resources.getDimensionPixelSize(R.dimen.popup_smaller_radius);
mRoundedTop = new GradientDrawable();
- mRoundedTop.setColor(backgroundColor);
+ mRoundedTop.setColor(popupPrimaryColor);
mRoundedTop.setCornerRadii(new float[] { mOutlineRadius, mOutlineRadius, mOutlineRadius,
mOutlineRadius, smallerRadius, smallerRadius, smallerRadius, smallerRadius});
mRoundedBottom = new GradientDrawable();
- mRoundedBottom.setColor(backgroundColor);
+ mRoundedBottom.setColor(popupPrimaryColor);
mRoundedBottom.setCornerRadii(new float[] { smallerRadius, smallerRadius, smallerRadius,
smallerRadius, mOutlineRadius, mOutlineRadius, mOutlineRadius, mOutlineRadius});
mIterateChildrenTag = getContext().getString(R.string.popup_container_iterate_children);
- if (mActivityContext.shouldUseColorExtractionForPopup()) {
+ if (!ENABLE_MATERIAL_U_POPUP.get() && mActivityContext.canUseMultipleShadesForPopup()) {
mColorIds = new int[]{R.color.popup_shade_first, R.color.popup_shade_second,
R.color.popup_shade_third};
} else {
@@ -241,15 +242,23 @@
mlp.bottomMargin = 0;
if (colors != null) {
- backgroundColor = colors[numVisibleChild % colors.length];
+ if (!ENABLE_MATERIAL_U_POPUP.get()) {
+ backgroundColor = colors[numVisibleChild % colors.length];
+ }
+
+ if (ENABLE_MATERIAL_U_POPUP.get() && isShortcutContainer(view)) {
+ setChildColor(view, colors[0], colorAnimator);
+ mArrowColor = colors[0];
+ }
}
// Arrow color matches the first child or the last child.
- if (mIsAboveIcon || (numVisibleChild == 0 && viewGroup == this)) {
+ if (!ENABLE_MATERIAL_U_POPUP.get()
+ && (mIsAboveIcon || (numVisibleChild == 0 && viewGroup == this))) {
mArrowColor = backgroundColor;
}
- if (view instanceof ViewGroup && mIterateChildrenTag.equals(view.getTag())) {
+ if (view instanceof ViewGroup && isShortcutContainer(view)) {
assignMarginsAndBackgrounds((ViewGroup) view, backgroundColor);
numVisibleChild++;
continue;
@@ -287,6 +296,13 @@
}
/**
+ * Returns {@code true} if view is a layout container of shortcuts
+ */
+ boolean isShortcutContainer(View view) {
+ return mIterateChildrenTag.equals(view.getTag());
+ }
+
+ /**
* Sets the background color of the child.
*/
protected void setChildColor(View view, int color, AnimatorSet animatorSetOut) {
@@ -308,7 +324,7 @@
*/
protected void reorderAndShow(int viewsToFlip) {
setupForDisplay();
- boolean reverseOrder = mIsAboveIcon;
+ boolean reverseOrder = !ENABLE_MATERIAL_U_POPUP.get() && mIsAboveIcon;
if (reverseOrder) {
reverseOrder(viewsToFlip);
}
@@ -634,7 +650,7 @@
for (int i = group.getChildCount() - 1; i >= 0; --i) {
View view = group.getChildAt(i);
if (view.getVisibility() == VISIBLE && view instanceof ViewGroup) {
- if (mIterateChildrenTag.equals(view.getTag())) {
+ if (isShortcutContainer(view)) {
fadeInChildViews((ViewGroup) view, alphaValues, startDelay, duration, out);
continue;
}
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 4da588e..8fef5c6 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -17,12 +17,16 @@
package com.android.launcher3.popup;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SHORTCUTS;
+import static com.android.launcher3.Utilities.ATLEAST_P;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static java.util.Collections.emptyList;
+
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
import android.annotation.TargetApi;
@@ -39,6 +43,8 @@
import android.view.ViewGroup;
import android.widget.ImageView;
+import androidx.annotation.LayoutRes;
+
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.BubbleTextView;
@@ -82,20 +88,20 @@
public class PopupContainerWithArrow<T extends Context & ActivityContext>
extends ArrowPopup<T> implements DragSource, DragController.DragListener {
- private final List<DeepShortcutView> mShortcuts = new ArrayList<>();
+ private final List<DeepShortcutView> mDeepShortcuts = new ArrayList<>();
private final PointF mInterceptTouchDown = new PointF();
private final int mStartDragThreshold;
+ private static final int SHORTCUT_COLLAPSE_THRESHOLD = 6;
+
private BubbleTextView mOriginalIcon;
private int mNumNotifications;
private NotificationContainer mNotificationContainer;
private int mContainerWidth;
private ViewGroup mWidgetContainer;
-
private ViewGroup mDeepShortcutContainer;
-
private ViewGroup mSystemShortcutContainer;
protected PopupItemDragHandler mPopupItemDragHandler;
@@ -211,19 +217,27 @@
return null;
}
- final PopupContainerWithArrow<Launcher> container =
- (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
- R.layout.popup_container, launcher.getDragLayer(), false);
- container.configureForLauncher(launcher);
-
+ PopupContainerWithArrow<Launcher> container;
PopupDataProvider popupDataProvider = launcher.getPopupDataProvider();
- container.populateAndShow(icon,
- popupDataProvider.getShortcutCountForItem(item),
- popupDataProvider.getNotificationKeysForItem(item),
- launcher.getSupportedShortcuts()
- .map(s -> s.getShortcut(launcher, item, icon))
- .filter(Objects::nonNull)
- .collect(Collectors.toList()));
+ int deepShortcutCount = popupDataProvider.getShortcutCountForItem(item);
+ List<SystemShortcut> systemShortcuts = launcher.getSupportedShortcuts()
+ .map(s -> s.getShortcut(launcher, item, icon))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ if (ENABLE_MATERIAL_U_POPUP.get()) {
+ container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
+ R.layout.popup_container_material_u, launcher.getDragLayer(), false);
+ container.populateAndShowRowsMaterialU(icon, deepShortcutCount, systemShortcuts);
+ } else {
+ container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
+ R.layout.popup_container, launcher.getDragLayer(), false);
+ container.populateAndShow(
+ icon,
+ deepShortcutCount,
+ popupDataProvider.getNotificationKeysForItem(item),
+ systemShortcuts);
+ }
+ container.configureForLauncher(launcher);
launcher.refreshAndBindWidgetsForPackageUser(PackageUserKey.fromItemInfo(item));
container.requestFocus();
return container;
@@ -246,7 +260,7 @@
initializeSystemShortcut(R.layout.system_shortcut, this, shortcuts.get(0));
return;
}
- mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons, this);
+ mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons_container, this);
for (SystemShortcut shortcut : shortcuts) {
initializeSystemShortcut(
R.layout.system_shortcut_icon_only, mSystemShortcutContainer,
@@ -281,17 +295,7 @@
mDeepShortcutContainer = findViewById(R.id.deep_shortcuts_container);
}
if (hasDeepShortcuts) {
- // Remove the widget shortcut fom the list
- List<SystemShortcut> systemShortcuts = shortcuts
- .stream()
- .filter(shortcut -> !(shortcut instanceof SystemShortcut.Widgets))
- .collect(Collectors.toList());
- Optional<SystemShortcut.Widgets> widgetShortcutOpt = shortcuts
- .stream()
- .filter(shortcut -> shortcut instanceof SystemShortcut.Widgets)
- .map(SystemShortcut.Widgets.class::cast)
- .findFirst();
-
+ List<SystemShortcut> systemShortcuts = getNonWidgetSystemShortcuts(shortcuts);
// if there are deep shortcuts, we might want to increase the width of shortcuts to fit
// horizontally laid out system shortcuts.
mContainerWidth = Math.max(mContainerWidth,
@@ -304,10 +308,10 @@
for (int i = shortcutCount; i > 0; i--) {
DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut, mDeepShortcutContainer);
v.getLayoutParams().width = mContainerWidth;
- mShortcuts.add(v);
+ mDeepShortcuts.add(v);
}
updateHiddenShortcuts();
-
+ Optional<SystemShortcut.Widgets> widgetShortcutOpt = getWidgetShortcut(shortcuts);
if (widgetShortcutOpt.isPresent()) {
if (mWidgetContainer == null) {
mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container,
@@ -327,21 +331,151 @@
}
reorderAndShow(viewsToFlip);
+ showPopupContainer((ItemInfo) originalIcon.getTag(), notificationKeys);
+ }
- ItemInfo originalItemInfo = (ItemInfo) originalIcon.getTag();
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- setAccessibilityPaneTitle(getTitleForAccessibility());
+ /**
+ * Populate and show shortcuts for the Launcher U app shortcut design.
+ * Will inflate the container and shortcut View instances for the popup container.
+ * @param originalIcon App icon that the popup is shown for
+ * @param deepShortcutCount Number of DeepShortcutView instances to add to container
+ * @param systemShortcuts List of SystemShortcuts to add to container
+ */
+ public void populateAndShowRowsMaterialU(final BubbleTextView originalIcon,
+ int deepShortcutCount, List<SystemShortcut> systemShortcuts) {
+
+ mOriginalIcon = originalIcon;
+ mContainerWidth = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_width);
+
+ if (deepShortcutCount > 0) {
+ addAllShortcutsMaterialU(deepShortcutCount, systemShortcuts);
+ } else if (!systemShortcuts.isEmpty()) {
+ addSystemShortcutsMaterialU(systemShortcuts,
+ R.layout.system_shortcut_rows_container_material_u,
+ R.layout.system_shortcut);
}
- mOriginalIcon.setForceHideDot(true);
+ // no reversing needed for U design
+ reorderAndShow(0);
+ showPopupContainer((ItemInfo) originalIcon.getTag(), /* notificationKeys= */ emptyList());
+ }
+ /**
+ * Animates and loads shortcuts on background thread for this popup container
+ */
+ private void showPopupContainer(ItemInfo originalItemInfo,
+ List<NotificationKeyData> notificationKeys) {
+
+ if (ATLEAST_P) {
+ setAccessibilityPaneTitle(getTitleForAccessibility());
+ }
+ mOriginalIcon.setForceHideDot(true);
// All views are added. Animate layout from now on.
setLayoutTransition(new LayoutTransition());
-
// Load the shortcuts on a background thread and update the container as it animates.
MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(PopupPopulator.createUpdateRunnable(
mActivityContext, originalItemInfo, new Handler(Looper.getMainLooper()),
- this, mShortcuts, notificationKeys));
+ this, mDeepShortcuts, notificationKeys));
+ }
+
+ /**
+ * Adds any Deep Shortcuts, System Shortcuts and the Widget Shortcut to their respective
+ * containers
+ * @param deepShortcutCount number of DeepShortcutView instances
+ * @param systemShortcuts List of SystemShortcuts
+ */
+ private void addAllShortcutsMaterialU(int deepShortcutCount,
+ List<SystemShortcut> systemShortcuts) {
+
+ if (deepShortcutCount + systemShortcuts.size() <= SHORTCUT_COLLAPSE_THRESHOLD) {
+ // add all system shortcuts including widgets shortcut to same container
+ addSystemShortcutsMaterialU(systemShortcuts,
+ R.layout.system_shortcut_rows_container_material_u,
+ R.layout.system_shortcut);
+ addDeepShortcutsMaterialU(deepShortcutCount);
+ return;
+ }
+
+ List<SystemShortcut> nonWidgetSystemShortcuts =
+ getNonWidgetSystemShortcuts(systemShortcuts);
+ // If total shortcuts over threshold, collapse system shortcuts to single row
+ addSystemShortcutsMaterialU(nonWidgetSystemShortcuts,
+ R.layout.system_shortcut_icons_container_material_u,
+ R.layout.system_shortcut_icon_only);
+ // May need to recalculate row width
+ mContainerWidth = Math.max(mContainerWidth,
+ nonWidgetSystemShortcuts.size() * getResources()
+ .getDimensionPixelSize(R.dimen.system_shortcut_header_icon_touch_size));
+ // Add widget shortcut to separate container
+ Optional<SystemShortcut.Widgets> widgetShortcutOpt = getWidgetShortcut(systemShortcuts);
+ if (widgetShortcutOpt.isPresent()) {
+ mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container_material_u,
+ this);
+ initializeWidgetShortcut(mWidgetContainer, widgetShortcutOpt.get());
+ }
+ addDeepShortcutsMaterialU(deepShortcutCount);
+ }
+
+ /**
+ * Finds the first instance of the Widgets Shortcut from the SystemShortcut List
+ * @param systemShortcuts List of SystemShortcut instances to search
+ * @return Optional Widgets SystemShortcut
+ */
+ private static Optional<SystemShortcut.Widgets> getWidgetShortcut(
+ List<SystemShortcut> systemShortcuts) {
+ return systemShortcuts
+ .stream()
+ .filter(shortcut -> shortcut instanceof SystemShortcut.Widgets)
+ .map(SystemShortcut.Widgets.class::cast)
+ .findFirst();
+ }
+
+ /**
+ * Returns list of [systemShortcuts] without the Widgets shortcut instance if found
+ * @param systemShortcuts list of SystemShortcuts to filter from
+ * @return systemShortcuts without the Widgets Shortcut
+ */
+ private static List<SystemShortcut> getNonWidgetSystemShortcuts(
+ List<SystemShortcut> systemShortcuts) {
+
+ return systemShortcuts
+ .stream()
+ .filter(shortcut -> !(shortcut instanceof SystemShortcut.Widgets))
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Inflates the given systemShortcutContainerLayout as a container, and populates with
+ * the systemShortcuts as views using the systemShortcutLayout
+ * @param systemShortcuts List of SystemShortcut to inflate as Views
+ * @param systemShortcutContainerLayout Layout Resource for the Container of shortcut Views
+ * @param systemShortcutLayout Layout Resource for the individual shortcut Views
+ */
+ private void addSystemShortcutsMaterialU(List<SystemShortcut> systemShortcuts,
+ @LayoutRes int systemShortcutContainerLayout, @LayoutRes int systemShortcutLayout) {
+
+ if (systemShortcuts.size() == 0) {
+ return;
+ }
+ mSystemShortcutContainer = inflateAndAdd(systemShortcutContainerLayout, this);
+ for (SystemShortcut shortcut : systemShortcuts) {
+ initializeSystemShortcut(systemShortcutLayout, mSystemShortcutContainer, shortcut);
+ }
+ }
+
+ /**
+ * Inflates and adds [deepShortcutCount] number of DeepShortcutView for the to a new container
+ * @param deepShortcutCount number of DeepShortcutView instances to add
+ */
+ private void addDeepShortcutsMaterialU(int deepShortcutCount) {
+ mDeepShortcutContainer = inflateAndAdd(R.layout.deep_shortcut_container, this);
+ for (int i = deepShortcutCount; i > 0; i--) {
+ DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut_material_u,
+ mDeepShortcutContainer);
+ v.getLayoutParams().width = mContainerWidth;
+ mDeepShortcuts.add(v);
+ }
+ updateHiddenShortcuts();
}
protected NotificationContainer getNotificationContainer() {
@@ -391,9 +525,9 @@
int allowedCount = mNotificationContainer != null
? MAX_SHORTCUTS_IF_NOTIFICATIONS : MAX_SHORTCUTS;
- int total = mShortcuts.size();
+ int total = mDeepShortcuts.size();
for (int i = 0; i < total; i++) {
- DeepShortcutView view = mShortcuts.get(i);
+ DeepShortcutView view = mDeepShortcuts.get(i);
view.setVisibility(i >= allowedCount ? GONE : VISIBLE);
}
}
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index c8455b8..2ffe34f 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -18,6 +18,7 @@
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.makeMeasureSpec;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import android.content.Context;
@@ -203,14 +204,22 @@
systemShortcuts.add(mPinnedAppsAdapter.getSystemShortcut(item, v));
}
systemShortcuts.add(APP_INFO.getShortcut(mActivity, item, v));
-
- final PopupContainerWithArrow container =
- (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
- R.layout.popup_container, mActivity.getDragLayer(), false);
-
- container.populateAndShow((BubbleTextView) v,
- popupDataProvider.getShortcutCountForItem(item),
- Collections.emptyList(), systemShortcuts);
+ int deepShortcutCount = popupDataProvider.getShortcutCountForItem(item);
+ final PopupContainerWithArrow<SecondaryDisplayLauncher> container;
+ if (ENABLE_MATERIAL_U_POPUP.get()) {
+ container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
+ R.layout.popup_container_material_u, mActivity.getDragLayer(), false);
+ container.populateAndShowRowsMaterialU((BubbleTextView) v, deepShortcutCount,
+ systemShortcuts);
+ } else {
+ container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
+ R.layout.popup_container, mActivity.getDragLayer(), false);
+ container.populateAndShow(
+ (BubbleTextView) v,
+ deepShortcutCount,
+ Collections.emptyList(),
+ systemShortcuts);
+ }
container.requestFocus();
if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) {
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 2ab4601..f7837f5 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -199,9 +199,9 @@
}
/**
- * Returns {@code true} if popups should use color extraction.
+ * Returns {@code true} if popups can use a range of color shades instead of a singular color.
*/
- default boolean shouldUseColorExtractionForPopup() {
+ default boolean canUseMultipleShadesForPopup() {
return true;
}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 5b57e22..315cbad 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -15,12 +15,16 @@
*/
package com.android.launcher3.views;
+import static androidx.core.content.ContextCompat.getColorStateList;
+
+import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_BUTTON_TAP_OR_LONGPRESS;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
@@ -31,6 +35,7 @@
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
+import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.Nullable;
@@ -139,6 +144,16 @@
mTargetRect.roundOut(outPos);
}
+ @Override
+ public void assignMarginsAndBackgrounds(ViewGroup viewGroup) {
+ if (ENABLE_MATERIAL_U_POPUP.get()) {
+ assignMarginsAndBackgrounds(viewGroup,
+ getColorStateList(getContext(), mColorIds[0]).getDefaultColor());
+ } else {
+ assignMarginsAndBackgrounds(viewGroup, Color.TRANSPARENT);
+ }
+ }
+
public static OptionsPopupView show(ActivityContext launcher, RectF targetRect,
List<OptionItem> items, boolean shouldAddArrow) {
return show(launcher, targetRect, items, shouldAddArrow, 0 /* width */);