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
This commit is contained in:
Jon Miranda
2021-03-18 11:08:49 -04:00
parent a79c7e4227
commit c79316740b
17 changed files with 188 additions and 101 deletions

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?attr/popupColorPrimary"/>
<corners android:radius="@dimen/popup_middle_item_radius" />
</shape>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?attr/popupColorPrimary"/>
<corners android:radius="@dimen/popup_single_item_radius" />
</shape>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?attr/popupColorSecondary"/>
<corners android:radius="@dimen/popup_single_item_radius" />
</shape>

View File

@@ -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" >
<com.android.launcher3.shortcuts.DeepShortcutTextView
@@ -45,12 +46,4 @@
android:layout_gravity="start|center_vertical"
android:background="@drawable/ic_deepshortcut_placeholder"/>
<View
android:id="@+id/divider"
android:layout_width="@dimen/deep_shortcuts_divider_width"
android:layout_height="@dimen/popup_item_divider_height"
android:layout_gravity="end|bottom"
android:visibility="gone"
android:background="?attr/popupColorTertiary" />
</com.android.launcher3.shortcuts.DeepShortcutView>

View File

@@ -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"

View File

@@ -96,14 +96,6 @@
</com.android.launcher3.notification.NotificationMainView>
<!-- Divider -->
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="@dimen/popup_item_divider_height"
android:layout_below="@id/main_view"
android:background="?attr/popupColorTertiary" />
<!-- Footer -->
<com.android.launcher3.notification.NotificationFooterLayout
android:id="@+id/footer"

View File

@@ -16,6 +16,5 @@
<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_marginTop="4dp"
android:background="@drawable/bg_notification_content" />
android:layout_height="0dp"
android:layout_marginTop="@dimen/popup_margin" />

View File

@@ -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" />
android:orientation="vertical">
<LinearLayout
android:id="@+id/notification_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:background="?attr/popupColorPrimary"
android:orientation="vertical"/>
</com.android.launcher3.popup.PopupContainerWithArrow>

View File

@@ -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" >
<com.android.launcher3.BubbleTextView
@@ -44,12 +45,4 @@
android:layout_gravity="start|center_vertical"
android:backgroundTint="?android:attr/textColorTertiary"/>
<View
android:id="@+id/divider"
android:layout_width="@dimen/deep_shortcuts_divider_width"
android:layout_height="@dimen/popup_item_divider_height"
android:layout_gravity="end|bottom"
android:visibility="gone"
android:background="?attr/popupColorTertiary" />
</com.android.launcher3.shortcuts.DeepShortcutView>

View File

@@ -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">
<Space android:layout_width="0dp"

View File

@@ -19,7 +19,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/round_rect_folder"
android:elevation="5dp"
android:orientation="vertical" >
<com.android.launcher3.folder.FolderPagedView

View File

@@ -176,16 +176,18 @@
<dimen name="pending_widget_elevation">2dp</dimen>
<!-- Deep shortcuts -->
<dimen name="deep_shortcuts_elevation">9dp</dimen>
<!-- also update deep_shortcuts_divider_width -->
<dimen name="deep_shortcuts_elevation">0dp</dimen>
<dimen name="bg_popup_item_width">234dp</dimen>
<dimen name="bg_popup_item_height">56dp</dimen>
<dimen name="bg_popup_item_condensed_height">48dp</dimen>
<dimen name="pre_drag_view_scale">6dp</dimen>
<!-- an icon with shortcuts must be dragged this far before the container is removed. -->
<dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
<dimen name="deep_shortcut_icon_size">36dp</dimen>
<dimen name="deep_shortcut_drawable_padding">8dp</dimen>
<dimen name="deep_shortcut_icon_size">32dp</dimen>
<dimen name="popup_margin">2dp</dimen>
<dimen name="popup_single_item_radius">100dp</dimen>
<dimen name="popup_middle_item_radius">4dp</dimen>
<dimen name="deep_shortcut_drawable_padding">12dp</dimen>
<dimen name="deep_shortcut_drag_handle_size">16dp</dimen>
<dimen name="popup_padding_start">10dp</dimen>
<dimen name="popup_padding_end">16dp</dimen>
@@ -194,16 +196,14 @@
<dimen name="popup_arrow_height">10dp</dimen>
<dimen name="popup_arrow_vertical_offset">-1dp</dimen>
<!-- popup_padding_start + deep_shortcut_icon_size / 2 -->
<dimen name="popup_arrow_horizontal_center_offset">28dp</dimen>
<dimen name="popup_arrow_horizontal_center_offset">26dp</dimen>
<dimen name="popup_arrow_corner_radius">2dp</dimen>
<!-- popup_padding_start + icon_size + 10dp -->
<dimen name="deep_shortcuts_text_padding_start">56dp</dimen>
<!-- popup_item_width - deep_shortcuts_text_padding_start -->
<dimen name="deep_shortcuts_divider_width">178dp</dimen>
<dimen name="deep_shortcuts_text_padding_start">52dp</dimen>
<dimen name="system_shortcut_icon_size">24dp</dimen>
<!-- popup_arrow_center_start - system_shortcut_icon_size / 2 -->
<!-- popup_arrow_horizontal_center_offset - system_shortcut_icon_size / 2 -->
<dimen name="system_shortcut_margin_start">16dp</dimen>
<dimen name="system_shortcut_header_height">48dp</dimen>
<dimen name="system_shortcut_header_height">56dp</dimen>
<dimen name="system_shortcut_header_icon_touch_size">48dp</dimen>
<!-- (touch_size - icon_size) / 2 -->
<dimen name="system_shortcut_header_icon_padding">12dp</dimen>

View File

@@ -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) {

View File

@@ -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<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> extends Abstrac
reverseOrder(viewsToFlip);
}
onInflationComplete(reverseOrder);
assignMarginsAndBackgrounds();
orientAboutObject();
if (shouldAddArrow()) {
addArrow();
}
@@ -176,6 +241,8 @@ public abstract class ArrowPopup<T extends BaseDraggingActivity> extends Abstrac
protected void show() {
setupForDisplay();
onInflationComplete(false);
assignMarginsAndBackgrounds();
orientAboutObject();
if (shouldAddArrow()) {
addArrow();
}
@@ -203,8 +270,6 @@ public abstract class ArrowPopup<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> extends Abstrac
? getResources().getInteger(R.integer.config_popupArrowOpenCloseDuration)
: 0;
}
private void animateOpen() {
setVisibility(View.VISIBLE);

View File

@@ -91,6 +91,7 @@ public class PopupContainerWithArrow<T extends BaseDraggingActivity> extends Arr
private BubbleTextView mOriginalIcon;
private NotificationItemView mNotificationItemView;
private int mNumNotifications;
private ViewGroup mNotificationContainer;
private ViewGroup mSystemShortcutContainer;
@@ -222,20 +223,6 @@ public class PopupContainerWithArrow<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> 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<T extends BaseDraggingActivity> extends Arr
mNotificationItemView.removeAllViews();
mNotificationItemView = null;
updateHiddenShortcuts();
updateDividers();
assignMarginsAndBackgrounds();
} else {
mNotificationItemView.trimNotifications(
NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys()));

View File

@@ -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() {

View File

@@ -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);