From c79316740b2be062efb8822f3b45b00876ba77d3 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Thu, 18 Mar 2021 11:08:49 -0400 Subject: [PATCH] Update deep shortcut to new ui. - Removed divider views, using margin to separate views - Removed elevations - Added a ViewGroup to hold all notification views, and applied an outline Bug: 175329686 Test: visual Change-Id: Iad70dcfdaeba6050c2b17c07f76bb7bfb728e544 --- res/drawable/middle_item_primary.xml | 20 ++++++ res/drawable/single_item_primary.xml | 20 ++++++ res/drawable/single_item_secondary.xml | 20 ++++++ res/layout/deep_shortcut.xml | 9 +-- res/layout/longpress_options_menu.xml | 1 - res/layout/notification_content.xml | 8 --- res/layout/notification_gutter.xml | 5 +- res/layout/popup_container.xml | 11 ++- res/layout/system_shortcut.xml | 9 +-- res/layout/system_shortcut_icons.xml | 2 +- res/layout/user_folder_icon_normalized.xml | 1 - res/values/dimens.xml | 20 +++--- .../notification/NotificationItemView.java | 46 +++++++----- .../android/launcher3/popup/ArrowPopup.java | 70 ++++++++++++++++++- .../popup/PopupContainerWithArrow.java | 40 +++-------- .../launcher3/shortcuts/DeepShortcutView.java | 6 -- .../launcher3/views/OptionsPopupView.java | 1 - 17 files changed, 188 insertions(+), 101 deletions(-) create mode 100644 res/drawable/middle_item_primary.xml create mode 100644 res/drawable/single_item_primary.xml create mode 100644 res/drawable/single_item_secondary.xml diff --git a/res/drawable/middle_item_primary.xml b/res/drawable/middle_item_primary.xml new file mode 100644 index 0000000000..c9757142da --- /dev/null +++ b/res/drawable/middle_item_primary.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/res/drawable/single_item_primary.xml b/res/drawable/single_item_primary.xml new file mode 100644 index 0000000000..1c0889bd23 --- /dev/null +++ b/res/drawable/single_item_primary.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/res/drawable/single_item_secondary.xml b/res/drawable/single_item_secondary.xml new file mode 100644 index 0000000000..4edc4813aa --- /dev/null +++ b/res/drawable/single_item_secondary.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml index 840a8b776d..d6b4a37dd4 100644 --- a/res/layout/deep_shortcut.xml +++ b/res/layout/deep_shortcut.xml @@ -19,6 +19,7 @@ xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="@dimen/bg_popup_item_width" android:layout_height="@dimen/bg_popup_item_height" + android:background="@drawable/middle_item_primary" android:theme="@style/PopupItem" > - - diff --git a/res/layout/longpress_options_menu.xml b/res/layout/longpress_options_menu.xml index 20bb5b81be..3898365b1c 100644 --- a/res/layout/longpress_options_menu.xml +++ b/res/layout/longpress_options_menu.xml @@ -18,7 +18,6 @@ android:id="@+id/deep_shortcuts_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="?attr/popupColorPrimary" android:clipToPadding="false" android:clipChildren="false" android:elevation="@dimen/deep_shortcuts_elevation" diff --git a/res/layout/notification_content.xml b/res/layout/notification_content.xml index d01be019eb..147aa30525 100644 --- a/res/layout/notification_content.xml +++ b/res/layout/notification_content.xml @@ -96,14 +96,6 @@ - - - \ No newline at end of file + android:layout_height="0dp" + android:layout_marginTop="@dimen/popup_margin" /> \ No newline at end of file diff --git a/res/layout/popup_container.xml b/res/layout/popup_container.xml index c73740771d..04822fd7a2 100644 --- a/res/layout/popup_container.xml +++ b/res/layout/popup_container.xml @@ -19,8 +19,15 @@ android:id="@+id/deep_shortcuts_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="?attr/popupColorPrimary" android:clipToPadding="false" android:clipChildren="false" android:elevation="@dimen/deep_shortcuts_elevation" - android:orientation="vertical" /> \ No newline at end of file + android:orientation="vertical"> + + \ No newline at end of file diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml index c620e2af57..68251e4d15 100644 --- a/res/layout/system_shortcut.xml +++ b/res/layout/system_shortcut.xml @@ -19,6 +19,7 @@ xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="@dimen/bg_popup_item_width" android:layout_height="@dimen/bg_popup_item_height" + android:background="@drawable/middle_item_primary" android:theme="@style/PopupItem" > - - diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml index a340f4fc9d..f9922488fb 100644 --- a/res/layout/system_shortcut_icons.xml +++ b/res/layout/system_shortcut_icons.xml @@ -21,7 +21,7 @@ android:layout_height="@dimen/system_shortcut_header_height" android:orientation="horizontal" android:gravity="end|center_vertical" - android:background="?attr/popupColorSecondary" + android:background="@drawable/single_item_secondary" android:clipToPadding="true"> 2dp - 9dp - + 0dp 234dp 56dp 48dp 6dp 16dp - 36dp - 8dp + 32dp + 2dp + 100dp + 4dp + 12dp 16dp 10dp 16dp @@ -194,16 +196,14 @@ 10dp -1dp - 28dp + 26dp 2dp - 56dp - - 178dp + 52dp 24dp - + 16dp - 48dp + 56dp 48dp 12dp diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java index 0320aa3edd..d44d158010 100644 --- a/src/com/android/launcher3/notification/NotificationItemView.java +++ b/src/com/android/launcher3/notification/NotificationItemView.java @@ -21,10 +21,13 @@ import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL; import android.app.Notification; import android.content.Context; import android.graphics.Color; +import android.graphics.Outline; import android.graphics.Rect; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; +import android.view.ViewOutlineProvider; import android.widget.TextView; import com.android.launcher3.R; @@ -43,7 +46,8 @@ public class NotificationItemView { private static final Rect sTempRect = new Rect(); private final Context mContext; - private final PopupContainerWithArrow mContainer; + private final PopupContainerWithArrow mPopupContainer; + private final ViewGroup mRootView; private final TextView mHeaderText; private final TextView mHeaderCount; @@ -53,7 +57,6 @@ public class NotificationItemView { private final View mIconView; private final View mHeader; - private final View mDivider; private View mGutter; @@ -61,8 +64,9 @@ public class NotificationItemView { private boolean mAnimatingNextIcon; private int mNotificationHeaderTextColor = Notification.COLOR_DEFAULT; - public NotificationItemView(PopupContainerWithArrow container) { - mContainer = container; + public NotificationItemView(PopupContainerWithArrow container, ViewGroup rootView) { + mPopupContainer = container; + mRootView = rootView; mContext = container.getContext(); mHeaderText = container.findViewById(R.id.notification_text); @@ -72,17 +76,25 @@ public class NotificationItemView { mIconView = container.findViewById(R.id.popup_item_icon); mHeader = container.findViewById(R.id.header); - mDivider = container.findViewById(R.id.divider); mSwipeDetector = new SingleAxisSwipeDetector(mContext, mMainView, HORIZONTAL); mSwipeDetector.setDetectableScrollConditions(SingleAxisSwipeDetector.DIRECTION_BOTH, false); mMainView.setSwipeDetector(mSwipeDetector); mFooter.setContainer(this); + + float radius = Themes.getDialogCornerRadius(mContext); + rootView.setClipToOutline(true); + rootView.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius); + } + }); } public void addGutter() { if (mGutter == null) { - mGutter = mContainer.inflateAndAdd(R.layout.notification_gutter, mContainer); + mGutter = mPopupContainer.inflateAndAdd(R.layout.notification_gutter, mRootView); } } @@ -94,9 +106,8 @@ public class NotificationItemView { } public void removeFooter() { - if (mContainer.indexOfChild(mFooter) >= 0) { - mContainer.removeView(mFooter); - mContainer.removeView(mDivider); + if (mRootView.indexOfChild(mFooter) >= 0) { + mRootView.removeView(mFooter); } } @@ -108,16 +119,15 @@ public class NotificationItemView { } public void removeAllViews() { - mContainer.removeView(mMainView); - mContainer.removeView(mHeader); + mRootView.removeView(mMainView); + mRootView.removeView(mHeader); - if (mContainer.indexOfChild(mFooter) >= 0) { - mContainer.removeView(mFooter); - mContainer.removeView(mDivider); + if (mRootView.indexOfChild(mFooter) >= 0) { + mRootView.removeView(mFooter); } if (mGutter != null) { - mContainer.removeView(mGutter); + mRootView.removeView(mGutter); } } @@ -136,11 +146,11 @@ public class NotificationItemView { public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { - sTempRect.set(mMainView.getLeft(), mMainView.getTop(), - mMainView.getRight(), mMainView.getBottom()); + sTempRect.set(mRootView.getLeft(), mRootView.getTop(), + mRootView.getRight(), mRootView.getBottom()); mIgnoreTouch = !sTempRect.contains((int) ev.getX(), (int) ev.getY()); if (!mIgnoreTouch) { - mContainer.getParent().requestDisallowInterceptTouchEvent(true); + mPopupContainer.getParent().requestDisallowInterceptTouchEvent(true); } } if (mIgnoreTouch) { diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index 15915e5380..6aa98122cd 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -28,6 +28,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Outline; import android.graphics.Rect; +import android.graphics.drawable.GradientDrawable; import android.util.AttributeSet; import android.util.Pair; import android.view.Gravity; @@ -48,6 +49,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.RevealOutlineAnimation; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; @@ -75,6 +77,8 @@ public abstract class ArrowPopup extends Abstrac private final int mArrowPointRadius; private final View mArrow; + private final int mMargin; + protected boolean mIsLeftAligned; protected boolean mIsAboveIcon; private int mGravity; @@ -84,6 +88,9 @@ public abstract class ArrowPopup extends Abstrac private final Rect mStartRect = new Rect(); private final Rect mEndRect = new Rect(); + private final GradientDrawable mRoundedTop; + private final GradientDrawable mRoundedBottom; + private Runnable mOnCloseCallback = () -> { }; public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) { @@ -103,6 +110,7 @@ public abstract class ArrowPopup extends Abstrac // Initialize arrow view final Resources resources = getResources(); + mMargin = resources.getDimensionPixelSize(R.dimen.popup_margin); mArrowWidth = resources.getDimensionPixelSize(R.dimen.popup_arrow_width); mArrowHeight = resources.getDimensionPixelSize(R.dimen.popup_arrow_height); mArrow = new View(context); @@ -111,6 +119,17 @@ public abstract class ArrowPopup extends Abstrac mArrowOffsetHorizontal = resources.getDimensionPixelSize( R.dimen.popup_arrow_horizontal_center_offset) - (mArrowWidth / 2); mArrowPointRadius = resources.getDimensionPixelSize(R.dimen.popup_arrow_corner_radius); + + mRoundedTop = new GradientDrawable(); + mRoundedTop.setColor(Themes.getAttrColor(context, R.attr.popupColorPrimary)); + mRoundedTop.setCornerRadii(new float[] { mOutlineRadius, mOutlineRadius, mOutlineRadius, + mOutlineRadius, 0, 0, 0, 0}); + + mRoundedBottom = new GradientDrawable(); + mRoundedBottom.setColor(Themes.getAttrColor(context, R.attr.popupColorPrimary)); + mRoundedBottom.setCornerRadii(new float[] { 0, 0, 0, 0, mOutlineRadius, mOutlineRadius, + mOutlineRadius, mOutlineRadius}); + } public ArrowPopup(Context context, AttributeSet attrs) { @@ -153,6 +172,50 @@ public abstract class ArrowPopup extends Abstrac */ protected void onInflationComplete(boolean isReversed) { } + /** + * Set the margins and radius of backgrounds after views are properly ordered. + */ + protected void assignMarginsAndBackgrounds() { + int count = getChildCount(); + int totalVisibleShortcuts = 0; + for (int i = 0; i < count; i++) { + View view = getChildAt(i); + if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) { + totalVisibleShortcuts++; + } + } + + int numVisibleShortcut = 0; + View lastView = null; + for (int i = 0; i < count; i++) { + View view = getChildAt(i); + boolean isShortcut = view instanceof DeepShortcutView; + if (view.getVisibility() == VISIBLE) { + if (lastView != null) { + MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams(); + mlp.bottomMargin = mMargin; + } + lastView = view; + MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams(); + mlp.bottomMargin = 0; + + if (isShortcut) { + if (totalVisibleShortcuts == 1) { + view.setBackgroundResource(R.drawable.single_item_primary); + } else if (totalVisibleShortcuts > 1) { + if (numVisibleShortcut == 0) { + view.setBackground(mRoundedTop); + } else if (numVisibleShortcut == (totalVisibleShortcuts - 1)) { + view.setBackground(mRoundedBottom); + } + numVisibleShortcut++; + } + } + } + } + measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + } + /** * Shows the popup at the desired location, optionally reversing the children. * @param viewsToFlip number of views from the top to to flip in case of reverse order @@ -164,6 +227,8 @@ public abstract class ArrowPopup extends Abstrac reverseOrder(viewsToFlip); } onInflationComplete(reverseOrder); + assignMarginsAndBackgrounds(); + orientAboutObject(); if (shouldAddArrow()) { addArrow(); } @@ -176,6 +241,8 @@ public abstract class ArrowPopup extends Abstrac protected void show() { setupForDisplay(); onInflationComplete(false); + assignMarginsAndBackgrounds(); + orientAboutObject(); if (shouldAddArrow()) { addArrow(); } @@ -203,8 +270,6 @@ public abstract class ArrowPopup extends Abstrac for (int i = 0; i < count; i++) { addView(allViews.get(i)); } - - orientAboutObject(); } private int getArrowLeft() { @@ -408,6 +473,7 @@ public abstract class ArrowPopup extends Abstrac ? getResources().getInteger(R.integer.config_popupArrowOpenCloseDuration) : 0; } + private void animateOpen() { setVisibility(View.VISIBLE); diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index a1ba74703c..4087f49f8e 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -91,6 +91,7 @@ public class PopupContainerWithArrow extends Arr private BubbleTextView mOriginalIcon; private NotificationItemView mNotificationItemView; private int mNumNotifications; + private ViewGroup mNotificationContainer; private ViewGroup mSystemShortcutContainer; @@ -222,20 +223,6 @@ public class PopupContainerWithArrow extends Arr if (isReversed && mNotificationItemView != null) { mNotificationItemView.inverseGutterMargin(); } - - // Update dividers - int count = getChildCount(); - DeepShortcutView lastView = null; - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) { - if (lastView != null) { - lastView.setDividerVisibility(VISIBLE); - } - lastView = (DeepShortcutView) view; - lastView.setDividerVisibility(INVISIBLE); - } - } } @TargetApi(Build.VERSION_CODES.P) @@ -257,8 +244,12 @@ public class PopupContainerWithArrow extends Arr // Add views if (mNumNotifications > 0) { // Add notification entries - View.inflate(getContext(), R.layout.notification_content, this); - mNotificationItemView = new NotificationItemView(this); + if (mNotificationContainer == null) { + mNotificationContainer = findViewById(R.id.notification_container); + mNotificationContainer.setVisibility(VISIBLE); + } + View.inflate(getContext(), R.layout.notification_content, mNotificationContainer); + mNotificationItemView = new NotificationItemView(this, mNotificationContainer); if (mNumNotifications == 1) { mNotificationItemView.removeFooter(); } @@ -358,21 +349,6 @@ public class PopupContainerWithArrow extends Arr } } - private void updateDividers() { - int count = getChildCount(); - DeepShortcutView lastView = null; - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) { - if (lastView != null) { - lastView.setDividerVisibility(VISIBLE); - } - lastView = (DeepShortcutView) view; - lastView.setDividerVisibility(INVISIBLE); - } - } - } - private void initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) { View view = inflateAndAdd( resId, container, getInsertIndexForSystemShortcut(container, info)); @@ -592,7 +568,7 @@ public class PopupContainerWithArrow extends Arr mNotificationItemView.removeAllViews(); mNotificationItemView = null; updateHiddenShortcuts(); - updateDividers(); + assignMarginsAndBackgrounds(); } else { mNotificationItemView.trimNotifications( NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys())); diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java index e9b92e2f10..1c1418c325 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java @@ -41,7 +41,6 @@ public class DeepShortcutView extends FrameLayout { private BubbleTextView mBubbleText; private View mIconView; - private View mDivider; private WorkspaceItemInfo mInfo; private ShortcutInfo mDetail; @@ -63,11 +62,6 @@ public class DeepShortcutView extends FrameLayout { super.onFinishInflate(); mBubbleText = findViewById(R.id.bubble_text); mIconView = findViewById(R.id.icon); - mDivider = findViewById(R.id.divider); - } - - public void setDividerVisibility(int visibility) { - mDivider.setVisibility(visibility); } public BubbleTextView getBubbleText() { diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java index 1a114f3ce7..9a2db109ef 100644 --- a/src/com/android/launcher3/views/OptionsPopupView.java +++ b/src/com/android/launcher3/views/OptionsPopupView.java @@ -134,7 +134,6 @@ public class OptionsPopupView extends ArrowPopup (DeepShortcutView) popup.inflateAndAdd(R.layout.system_shortcut, popup); view.getIconView().setBackgroundResource(item.iconRes); view.getBubbleText().setText(item.labelRes); - view.setDividerVisibility(View.INVISIBLE); view.setOnClickListener(popup); view.setOnLongClickListener(popup); popup.mItemMap.put(view, item);