Add swipe-to-dismiss notifications in popup menu.
- Next secondary icon animates up to replace dismissed main notification
- Add padding around main notification so it always aligns with the
straight edges of the view (not the rounded corners); looks more
dismissable
- Notification view collapses as notifications are dismissed
- To mimic system notification behavior, we copy SwipeHelper,
FlingAnimationUtils, and Interpolators. We also apply elevation
to notifications and reveal a darker color beneath when dismissing.
Bug: 32410600
Change-Id: I9fbf10e73bb4996f17ef061c856efb013967d972
diff --git a/res/drawable/bg_white_pill_bottom.xml b/res/drawable/bg_white_pill_bottom.xml
new file mode 100644
index 0000000..a1ea48c
--- /dev/null
+++ b/res/drawable/bg_white_pill_bottom.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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="#FFFFFF" />
+ <corners android:bottomLeftRadius="@dimen/bg_pill_radius"
+ android:bottomRightRadius="@dimen/bg_pill_radius" />
+</shape>
\ No newline at end of file
diff --git a/res/drawable/bg_white_pill_top.xml b/res/drawable/bg_white_pill_top.xml
new file mode 100644
index 0000000..9988b29
--- /dev/null
+++ b/res/drawable/bg_white_pill_top.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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="#FFFFFF" />
+ <corners android:topLeftRadius="@dimen/bg_pill_radius"
+ android:topRightRadius="@dimen/bg_pill_radius" />
+</shape>
\ No newline at end of file
diff --git a/res/layout/notification.xml b/res/layout/notification.xml
new file mode 100644
index 0000000..d828c4a
--- /dev/null
+++ b/res/layout/notification.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<com.android.launcher3.notification.NotificationItemView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/notification_view"
+ android:layout_width="@dimen/bg_pill_width"
+ android:layout_height="wrap_content"
+ android:elevation="@dimen/deep_shortcuts_elevation"
+ android:background="@drawable/bg_white_pill">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:clipChildren="false">
+
+ <TextView
+ android:id="@+id/header"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_footer_collapsed_height"
+ android:gravity="center_vertical"
+ android:textAlignment="center"
+ android:text="@string/notifications_header"
+ android:elevation="@dimen/notification_elevation"
+ android:background="@drawable/bg_white_pill_top" />
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_divider_height"
+ android:layout_below="@id/header" />
+
+ <include layout="@layout/notification_main"
+ android:id="@+id/main_view"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/bg_pill_height"
+ android:layout_below="@id/divider" />
+
+ <include layout="@layout/notification_footer"
+ android:id="@+id/footer"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_footer_height"
+ android:layout_below="@id/main_view" />
+
+ </RelativeLayout>
+
+</com.android.launcher3.notification.NotificationItemView>
diff --git a/res/layout/notification_footer.xml b/res/layout/notification_footer.xml
new file mode 100644
index 0000000..ceea24a
--- /dev/null
+++ b/res/layout/notification_footer.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+
+<com.android.launcher3.notification.NotificationFooterLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:background="@drawable/bg_white_pill_bottom"
+ android:elevation="@dimen/notification_elevation"
+ android:clipChildren="false" >
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_divider_height"/>
+
+ <LinearLayout
+ android:id="@+id/icon_row"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:padding="@dimen/notification_footer_icon_row_padding"
+ android:clipToPadding="false"
+ android:clipChildren="false"/>
+
+</com.android.launcher3.notification.NotificationFooterLayout>
+
diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml
new file mode 100644
index 0000000..efb74b0
--- /dev/null
+++ b/res/layout/notification_main.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+
+<com.android.launcher3.notification.NotificationMainView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:focusable="true"
+ android:background="@drawable/bg_pill_focused"
+ android:elevation="@dimen/notification_elevation" >
+
+ <View
+ android:id="@+id/popup_item_icon"
+ android:layout_width="@dimen/notification_icon_size"
+ android:layout_height="@dimen/notification_icon_size"
+ android:layout_marginStart="@dimen/notification_icon_margin_start"
+ android:layout_gravity="center_vertical" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:layout_marginStart="@dimen/notification_text_margin_start"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/title"
+ style="@style/Icon.DeepNotification"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:id="@+id/text"
+ style="@style/Icon.DeepNotification.SubText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+</com.android.launcher3.notification.NotificationMainView>
+
diff --git a/res/values/config.xml b/res/values/config.xml
index d270def..cb813d5 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -97,12 +97,13 @@
<!-- View ID used by PreviewImageView to cache its instance -->
<item type="id" name="preview_image_id" />
-<!-- Deep shortcuts -->
+<!-- Popup items -->
<integer name="config_deepShortcutOpenDuration">220</integer>
<integer name="config_deepShortcutArrowOpenDuration">80</integer>
<integer name="config_deepShortcutOpenStagger">40</integer>
<integer name="config_deepShortcutCloseDuration">150</integer>
<integer name="config_deepShortcutCloseStagger">20</integer>
+ <integer name="config_removeNotificationViewDuration">300</integer>
<!-- Accessibility actions -->
<item type="id" name="action_remove" />
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3a2eea6..2cf17ea 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -172,9 +172,22 @@
<!-- Icon badges (with notification counts) -->
<dimen name="badge_size">24dp</dimen>
<dimen name="badge_text_size">12dp</dimen>
+ <dimen name="notification_icon_size">28dp</dimen>
+ <dimen name="notification_footer_icon_size">24dp</dimen>
+ <!-- (icon_size - secondary_icon_size) / 2 -->
+
+<!-- Notifications -->
+ <dimen name="notification_footer_icon_row_padding">2dp</dimen>
+ <dimen name="notification_icon_margin_start">8dp</dimen>
+ <dimen name="notification_text_margin_start">8dp</dimen>
+ <dimen name="notification_footer_height">36dp</dimen>
+ <!-- The height to use when there are no icons in the footer -->
+ <dimen name="notification_footer_collapsed_height">@dimen/bg_pill_radius</dimen>
+ <dimen name="notification_elevation">2dp</dimen>
+ <dimen name="notification_divider_height">0.5dp</dimen>
+ <dimen name="swipe_helper_falsing_threshold">70dp</dimen>
<!-- Other -->
<!-- Approximates the system status bar height. Not guaranteed to be always be correct. -->
<dimen name="status_bar_height">24dp</dimen>
-
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f1de623..a6f44f6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -67,6 +67,13 @@
<!-- Label for the button which allows the user to get app search results. [CHAR_LIMIT=50] -->
<string name="all_apps_search_market_message">Search for more apps</string>
+ <!-- Deep items -->
+ <!-- Text to indicate more items that couldn't be displayed due to space constraints.
+ The text must fit in the size of a small icon [CHAR_LIMIT=3] -->
+ <string name="deep_notifications_overflow" translatable="false">+%1$d</string>
+ <!-- Text to display as the header above notifications. [CHAR_LIMIT=30] -->
+ <string name="notifications_header" translatable="false">Notifications</string>
+
<!-- Drag and drop -->
<skip />
<!-- Error message when user has filled a home screen -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 4e70f43..8b4a1db 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -112,6 +112,26 @@
<item name="iconSizeOverride">@dimen/deep_shortcut_icon_size</item>
</style>
+ <style name="Icon.DeepNotification">
+ <item name="android:gravity">start</item>
+ <item name="android:textAlignment">viewStart</item>
+ <item name="android:elevation">@dimen/deep_shortcuts_elevation</item>
+ <item name="android:textColor">#FF212121</item>
+ <item name="android:textSize">14sp</item>
+ <item name="android:fontFamily">sans-serif</item>
+ <item name="android:shadowRadius">0</item>
+ <item name="customShadows">false</item>
+ <item name="layoutHorizontal">true</item>
+ <item name="iconDisplay">shortcut_popup</item>
+ <item name="iconSizeOverride">@dimen/deep_shortcut_icon_size</item>
+ </style>
+
+ <style name="Icon.DeepNotification.SubText">
+ <item name="android:textColor">#FF757575</item>
+ <item name="android:textSize">12sp</item>
+ <item name="android:paddingEnd">4dp</item>
+ </style>
+
<!-- Drop targets -->
<style name="DropTargetButtonBase">
<item name="android:drawablePadding">7.5dp</item>