Merge "disable feature flag LAUNCHER3_PROMISE_APPS_IN_ALL_APPS" into ub-launcher3-dorval-polish
diff --git a/res/color-v24/all_apps_bg_hand_fill_dark.xml b/res/color-v24/all_apps_bg_hand_fill_dark.xml
new file mode 100644
index 0000000..bb9c71c
--- /dev/null
+++ b/res/color-v24/all_apps_bg_hand_fill_dark.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<gradient
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:startX="158.5"
+ android:startY="141.5"
+ android:endX="196.0"
+ android:endY="206.5"
+ android:type="linear" >
+ <item android:offset="0" android:color="#9AA0A6" />
+ <item android:offset="0.1013" android:color="#E5A5ABB0" />
+ <item android:offset="0.4946" android:color="#81CDCFD1" />
+ <item android:offset="0.8079" android:color="#31E5E6E6" />
+ <item android:offset="1" android:color="#00EEEEEE" />
+</gradient>
\ No newline at end of file
diff --git a/res/drawable/deep_shortcuts_drag_handle.xml b/res/drawable/deep_shortcuts_drag_handle.xml
index 82e844d..8fc3779 100644
--- a/res/drawable/deep_shortcuts_drag_handle.xml
+++ b/res/drawable/deep_shortcuts_drag_handle.xml
@@ -22,6 +22,7 @@
android:tint="?android:attr/textColorHint" >
<path
- android:pathData="M20 9H4v2h16V9zM4 15h16v-2H4v2z"
+ android:pathData="M19,9H5c-0.55,0-1,0.45-1,1l0,0c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1l0,0C20,9.45,19.55,9,19,9z M5,
+ 15h14c0.55,0,1-0.45,1-1l0,0c0-0.55-0.45-1-1-1H5c-0.55,0-1,0.45-1,1l0,0C4,14.55,4.45,15,5,15z"
android:fillColor="@android:color/white" />
</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_all_apps_bg_hand.xml b/res/drawable/ic_all_apps_bg_hand.xml
index 94af008..7f3fe14 100644
--- a/res/drawable/ic_all_apps_bg_hand.xml
+++ b/res/drawable/ic_all_apps_bg_hand.xml
@@ -42,7 +42,7 @@
c0.3,1.7,1.9,2.9,3.6,2.7l40-6.1c1.7-0.3,2.9-1.9,2.7-3.6L54.4,21L41.7,23z M37.5,23.6l-12.6,1.9l-0.3-2.1l12.6-1.9L37.5,23.6z"/>
</group>
<path
- android:fillColor="#BDBDBD"
+ android:fillColor="?android:attr/colorControlHighlight"
android:pathData="M87.5,62.9h-4.4l-1.6-1.5c5.5-6.4,8.8-14.7,8.8-23.7C90.3,17.7,74,1.4,54,1.4
S17.6,17.7,17.6,37.7S33.9,74.1,54,74.1c9,0,17.3-3.3,23.7-8.8l1.5,1.6v4.4l40.5,40.4l8.3-8.3L87.5,62.9z M54,64.2
c-14.7,0-26.5-11.8-26.5-26.5S39.3,11.2,54,11.2s26.5,11.8,26.5,26.5S68.6,64.2,54,64.2z"/>
@@ -92,7 +92,7 @@
c-0.7-0.1-1.3-0.2-2,0.2c-1,0.6-1.2,1.5-1.3,2.4c-0.2,1.8,0.6,3.9,1.6,5.9L107,87.3l0.2,0.4l6.6,11.7l0,0
c2.5,4.5,4.4,10.5,4.4,10.7L129.7,125.1"/>
<path
- android:fillColor="@color/all_apps_bg_hand_fill"
+ android:fillColor="?android:attr/colorForeground"
android:pathData="M202.3,183.1c-5.4-14.1-23.8-44.3-26.7-49c-0.2-0.3-0.6-0.3-0.8,0
c-5.1,6.6-19,11.4-26.5,13.6c-0.3,0.1-1,0.1-1.2,0.6c-0.2,0.4,0.1,1,0.2,1.1c7.8,12.9,14.7,27.9,15.3,29.3c0,0.1,0.1,0.1,0.1,0.2
l9.6,22.9c0,0,0,0,0,0l1.7,4.1c1.4,2.7,3,4.3,5.3,5.1c1.5,0.5,2.1,0.6,3.2,0.6c4.8,0.1,15.2-6.1,20.5-9.4c2.7-1.7,3.3-4.4,2.9-7.6
diff --git a/res/drawable/ic_all_apps_bg_icon_1.xml b/res/drawable/ic_all_apps_bg_icon_1.xml
index c9c0a75..d226ac6 100644
--- a/res/drawable/ic_all_apps_bg_icon_1.xml
+++ b/res/drawable/ic_all_apps_bg_icon_1.xml
@@ -25,7 +25,7 @@
android:pathData="M44.28,30.96c4.84-10.68,0.09-23.27-10.59-28.11S10.42,2.74,5.58,13.42
C1,23.54,6.5,35.92,16.62,40.51l0,0l-3.23,7.12C27.84,47,39.79,40.86,44.28,30.96z" />
<path
- android:fillColor="#E0E0E0"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M41.75,30.05c4.84-10.68,0.09-23.27-10.59-28.11S7.9,1.83,3.06,12.51
c-4.59,10.12,0.92,22.5,11.03,27.09l0,0l-3.23,7.12C25.31,46.09,37.26,39.94,41.75,30.05z" />
</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_all_apps_bg_icon_2.xml b/res/drawable/ic_all_apps_bg_icon_2.xml
index b6269e3..5966d99 100644
--- a/res/drawable/ic_all_apps_bg_icon_2.xml
+++ b/res/drawable/ic_all_apps_bg_icon_2.xml
@@ -26,7 +26,7 @@
c-0.25-0.58-0.9-0.99-1.89-1.1L6.2,5.99C5.39,5.91,4.74,6.08,4.32,6.44l0,0C3.7,6.97,3.55,7.88,4.01,8.96l14.54,34.09
C19,44.13,19.75,44.65,20.54,44.59L20.54,44.59z" />
<path
- android:fillColor="#E0E0E0"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M18.49,43.22c0.57-0.04,1.15-0.38,1.67-1.04l24.23-30.62c0.62-0.78,0.77-1.54,0.52-2.12
c-0.25-0.58-0.9-0.99-1.89-1.1L4.15,4.62C3.34,4.54,2.69,4.71,2.27,5.08l0,0C1.65,5.6,1.5,6.52,1.96,7.6L16.5,41.69
C16.96,42.76,17.7,43.28,18.49,43.22L18.49,43.22z" />
diff --git a/res/drawable/ic_all_apps_bg_icon_3.xml b/res/drawable/ic_all_apps_bg_icon_3.xml
index 4c255a9..b18f8bc 100644
--- a/res/drawable/ic_all_apps_bg_icon_3.xml
+++ b/res/drawable/ic_all_apps_bg_icon_3.xml
@@ -26,11 +26,11 @@
s22.31-9.99,22.31-22.31S37.5,1.27,25.18,1.27z M25.18,33.55c-5.5,0-14.35-5.1-14.35-10.6s8.32-12.19,13.82-12.19
c5.5,0,10.49,7.33,10.49,12.83S30.68,33.55,25.18,33.55z" />
<path
- android:fillColor="#E0E0E0"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M22.93,0.22c-12.32,0-22.31,9.99-22.31,22.31s9.99,22.31,22.31,22.31
s22.31-9.99,22.31-22.31S35.25,0.22,22.93,0.22z M22.93,32.5c-5.5,0-9.97-4.46-9.97-9.97s4.46-9.97,9.97-9.97
c5.5,0,9.97,4.46,9.97,9.97S28.43,32.5,22.93,32.5z" />
<path
- android:fillColor="#E0E0E0"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M14.81,22.53a8.12,8.12 0 1,0 16.24,0a8.12,8.12 0 1,0 -16.24,0z" />
</vector>
diff --git a/res/drawable/ic_all_apps_bg_icon_4.xml b/res/drawable/ic_all_apps_bg_icon_4.xml
index 12e05bc..8eb4d90 100644
--- a/res/drawable/ic_all_apps_bg_icon_4.xml
+++ b/res/drawable/ic_all_apps_bg_icon_4.xml
@@ -25,7 +25,7 @@
android:pathData="M11.53,8.02l23.39-5.73c1.61-0.39,3.25,0.6,3.64,2.21l7.64,31.19
c0.39,1.61-0.6,3.25-2.21,3.64L12.8,46.97c-1.61,0.39-3.25-0.6-3.64-2.21L3.43,21.37L11.53,8.02z" />
<path
- android:fillColor="#E0E0E0"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M9.2,6.53L32.59,0.8C34.2,0.4,35.84,1.4,36.23,3l7.64,31.19c0.39,1.61-0.6,3.25-2.21,3.64
l-31.19,7.64c-1.61,0.39-3.25-0.6-3.64-2.21L1.11,19.87L9.2,6.53z" />
<path
diff --git a/res/drawable/ic_info_no_shadow.xml b/res/drawable/ic_info_no_shadow.xml
index 91a3a56..b5512c3 100644
--- a/res/drawable/ic_info_no_shadow.xml
+++ b/res/drawable/ic_info_no_shadow.xml
@@ -21,5 +21,7 @@
android:tint="?android:attr/textColorPrimary" >
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"/>
+ android:pathData="M12,17L12,17c0.55,0,1-0.45,1-1v-4c0-0.55-0.45-1-1-1l0,0c-0.55,0-1,0.45-1,1v4C11,16.55,11.45,17,12,17z M12,2C6.48,
+ 2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8S16.41,20,12,20zM12,
+ 9.1L12,9.1c0.61,0,1.1-0.49,1.1-1.1l0,0c0-0.61-0.49-1.1-1.1-1.1l0,0c-0.61,0-1.1,0.49-1.1,1.1l0,0C10.9,8.61,11.39,9.1,12,9.1z"/>
</vector>
diff --git a/res/drawable/ic_widget.xml b/res/drawable/ic_widget.xml
index 3e7bd7b..de2980f 100644
--- a/res/drawable/ic_widget.xml
+++ b/res/drawable/ic_widget.xml
@@ -20,5 +20,7 @@
android:viewportHeight="48.0">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M26 26v16h16V26H26zM6 42h16V26H6v16zM6 6v16h16V6H6zm27.31-2.63L22 14.69 33.31 26l11.31-11.31L33.31 3.37z"/>
+ android:pathData="M26,28v12c0,1,0.8,2,2,2h12c1,0,2-1,2-2V28c0-1.2-1-2-2-2H28C26.8,26,26,26.8,26,28z M8,42h12c1.2,0,2-1,2-2V28
+ c0-1.2-0.8-2-2-2H8c-1,0-2,0.8-2,2v12C6,41,7,42,8,42z M6,8v12c0,1.2,1,2,2,2h12c1.2,0,2-0.8,2-2V8c0-1-0.8-2-2-2H8C7,6,6,7,6,8z
+ M32.6,4.6l-8,8c-0.8,0.8-0.8,2,0,2.8l8,8c0.8,0.8,2,0.8,2.8,0l8-8c0.8-0.8,0.8-2,0-2.8l-8-8C34.6,3.8,33.4,3.8,32.6,4.6z"/>
</vector>
diff --git a/res/layout/all_apps_icon.xml b/res/layout/all_apps_icon.xml
index ca0cbcc..79fb612 100644
--- a/res/layout/all_apps_icon.xml
+++ b/res/layout/all_apps_icon.xml
@@ -23,7 +23,6 @@
android:stateListAnimator="@animator/all_apps_fastscroll_icon_anim"
launcher:iconDisplay="all_apps"
launcher:centerVertically="true"
- android:paddingLeft="4dp"
- android:paddingRight="4dp"
- android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding" />
+ android:paddingLeft="@dimen/dynamic_grid_cell_padding_x"
+ android:paddingRight="@dimen/dynamic_grid_cell_padding_x" />
diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml
index b2443f5..7a8cf6d 100644
--- a/res/layout/notification_main.xml
+++ b/res/layout/notification_main.xml
@@ -30,7 +30,8 @@
android:gravity="center_vertical"
android:background="?attr/popupColorPrimary"
android:paddingStart="@dimen/notification_padding_start"
- android:paddingEnd="@dimen/notification_main_text_padding_end">
+ android:paddingEnd="@dimen/notification_main_text_padding_end"
+ android:paddingBottom="16dp">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
@@ -58,6 +59,7 @@
android:layout_width="@dimen/notification_icon_size"
android:layout_height="@dimen/notification_icon_size"
android:layout_marginEnd="@dimen/notification_padding_end"
+ android:layout_marginBottom="8dp"
android:layout_gravity="center_vertical|end" />
</com.android.launcher3.notification.NotificationMainView>
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index e29e5b1..c5ef6e0 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -23,6 +23,6 @@
android:id="@+id/all_apps_handle"
android:layout_width="48dp"
android:layout_height="match_parent"
- android:layout_gravity="center"
+ android:layout_gravity="top|center"
android:scaleType="centerInside"/>
</com.android.launcher3.pageindicators.PageIndicatorLineCaret>
diff --git a/res/layout/qsb_default_view.xml b/res/layout/qsb_default_view.xml
index 3075f80..04fe236 100644
--- a/res/layout/qsb_default_view.xml
+++ b/res/layout/qsb_default_view.xml
@@ -21,7 +21,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
- android:layout_margin="16dp"
+ android:layout_margin="8dp"
android:layout_gravity="center_vertical"
android:background="@drawable/round_rect_primary"
android:elevation="2dp"
diff --git a/res/layout/shortcuts_item.xml b/res/layout/shortcuts_item.xml
index e54462e..7cd996d 100644
--- a/res/layout/shortcuts_item.xml
+++ b/res/layout/shortcuts_item.xml
@@ -22,10 +22,18 @@
android:elevation="@dimen/deep_shortcuts_elevation">
<LinearLayout
- android:id="@+id/deep_shortcuts"
+ android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
+
+ <!-- The shortcuts header is added at runtime when necessary. -->
+
+ <LinearLayout
+ android:id="@+id/shortcuts"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" />
</LinearLayout>
</com.android.launcher3.shortcuts.ShortcutsItemView>
diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml
index db59d49..34d63e7 100644
--- a/res/layout/system_shortcut_icons.xml
+++ b/res/layout/system_shortcut_icons.xml
@@ -21,4 +21,7 @@
android:layout_height="@dimen/system_shortcut_header_height"
android:orientation="horizontal"
android:gravity="end|center_vertical"
- android:background="?attr/popupColorSecondary" />
+ android:background="?attr/popupColorSecondary"
+ android:elevation="1dp"
+ android:outlineProvider="none" />
+ <!-- We have elevation so this is drawn on top, but no outline provider to remove shadow -->
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index b7189d1..27992ce 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -130,6 +130,6 @@
<attr name="android:src" />
<attr name="android:shadowColor" />
<attr name="android:elevation" />
- <attr name="android:tint" />
+ <attr name="darkTintColor" format="color"/>
</declare-styleable>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 4f7c1a7..b44a31e 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -39,4 +39,5 @@
<color name="legacy_icon_background">#FFFFFF</color>
<color name="all_apps_bg_hand_fill">#E5E5E5</color>
+ <color name="all_apps_bg_hand_fill_dark">#9AA0A6</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 57b4be4..b90de82 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -16,8 +16,8 @@
<resources>
<!-- Dynamic Grid -->
- <dimen name="dynamic_grid_edge_margin">8dp</dimen>
- <dimen name="dynamic_grid_page_indicator_height">28dp</dimen>
+ <dimen name="dynamic_grid_edge_margin">16dp</dimen>
+ <dimen name="dynamic_grid_page_indicator_height">32dp</dimen>
<dimen name="dynamic_grid_page_indicator_line_height">1dp</dimen>
<dimen name="dynamic_grid_page_indicator_gutter_width_left_nav_bar">38dp</dimen>
<dimen name="dynamic_grid_page_indicator_gutter_width_right_nav_bar">48dp</dimen>
@@ -26,14 +26,17 @@
<dimen name="dynamic_grid_overview_max_icon_zone_height">120dp</dimen>
<dimen name="dynamic_grid_overview_bar_item_width">80dp</dimen>
<dimen name="dynamic_grid_overview_bar_spacer_width">25dp</dimen>
- <dimen name="dynamic_grid_workspace_top_padding">12dp</dimen>
+ <dimen name="dynamic_grid_workspace_top_padding">8dp</dimen>
<dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
<!-- Minimum space between workspace and hotseat in spring loaded mode -->
<dimen name="dynamic_grid_min_spring_loaded_space">8dp</dimen>
+ <!-- dynamic_grid_edge_margin / 2 -->
+ <dimen name="dynamic_grid_cell_padding_x">8dp</dimen>
+
<!-- Hotseat -->
<dimen name="dynamic_grid_hotseat_top_padding">8dp</dimen>
- <dimen name="dynamic_grid_hotseat_bottom_padding">0dp</dimen>
+ <dimen name="dynamic_grid_hotseat_bottom_padding">2dp</dimen>
<dimen name="dynamic_grid_hotseat_height">80dp</dimen>
<dimen name="dynamic_grid_hotseat_land_gutter_width">24dp</dimen>
@@ -152,6 +155,7 @@
<dimen name="deep_shortcuts_elevation">9dp</dimen>
<dimen name="bg_popup_item_width">220dp</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>
@@ -195,7 +199,7 @@
<!-- notification_padding_end + (icon_size - footer_icon_size) / 2 -->
<dimen name="notification_footer_icon_row_padding">15dp</dimen>
<dimen name="notification_header_height">32dp</dimen>
- <dimen name="notification_main_height">80dp</dimen>
+ <dimen name="notification_main_height">96dp</dimen>
<dimen name="notification_footer_height">32dp</dimen>
<dimen name="notification_header_text_size">13sp</dimen>
<dimen name="notification_header_count_text_size">12sp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 594c7db..b982136 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -156,4 +156,15 @@
<style name="TextTitle">
<item name="android:fontFamily">sans-serif</item>
</style>
+
+ <style name="AllAppsEmptySearchBackground">
+ <item name="android:colorPrimary">#E0E0E0</item>
+ <item name="android:colorControlHighlight">#BDBDBD</item>
+ <item name="android:colorForeground">@color/all_apps_bg_hand_fill</item>
+ </style>
+ <style name="AllAppsEmptySearchBackground.Dark">
+ <item name="android:colorPrimary">#9AA0A6</item>
+ <item name="android:colorControlHighlight">#DFE1E5</item>
+ <item name="android:colorForeground">@color/all_apps_bg_hand_fill_dark</item>
+ </style>
</resources>
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index b6e7328..f8e87c5 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -168,6 +168,7 @@
int defaultIconSize = grid.iconSizePx;
if (display == DISPLAY_WORKSPACE) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
+ setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
} else if (display == DISPLAY_ALL_APPS) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx);
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 8a477d8..e4a3226 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -102,8 +102,8 @@
protected void setDrawable(int resId) {
// We do not set the drawable in the xml as that inflates two drawables corresponding to
// drawableLeft and drawableStart.
- mDrawable = getResources().getDrawable(resId);
- setCompoundDrawablesRelativeWithIntrinsicBounds(mDrawable, null, null, null);
+ setCompoundDrawablesRelativeWithIntrinsicBounds(resId, 0, 0, 0);
+ mDrawable = getCompoundDrawablesRelative()[0];
}
public void setDropTargetBar(DropTargetBar dropTargetBar) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 83ea067..0a346a6 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -32,6 +32,7 @@
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.badge.BadgeRenderer;
+import com.android.launcher3.config.FeatureFlags;
import java.util.ArrayList;
@@ -92,6 +93,7 @@
public int cellWidthPx;
public int cellHeightPx;
+ public int cellPaddingXPx;
// Folder
public int folderBackgroundOffset;
@@ -192,6 +194,8 @@
workspaceSpringLoadedBottomSpace =
res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
+ cellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
+
hotseatBarTopPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
hotseatBarBottomPaddingPx =
@@ -264,36 +268,34 @@
}
private void updateAvailableDimensions(DisplayMetrics dm, Resources res) {
- updateIconSize(1f, iconDrawablePaddingOriginalPx, res, dm);
+ updateIconSize(1f, res, dm);
// Check to see if the icons fit within the available height. If not, then scale down.
float usedHeight = (cellHeightPx * inv.numRows);
int maxHeight = (availableHeightPx - getTotalWorkspacePadding().y);
if (usedHeight > maxHeight) {
float scale = maxHeight / usedHeight;
- updateIconSize(scale, 0, res, dm);
+ updateIconSize(scale, res, dm);
}
-
updateAvailableFolderCellDimensions(dm, res);
}
- private void updateIconSize(float scale, int drawablePadding, Resources res,
- DisplayMetrics dm) {
+ private void updateIconSize(float scale, Resources res, DisplayMetrics dm) {
iconSizePx = (int) (Utilities.pxFromDp(inv.iconSize, dm) * scale);
iconTextSizePx = (int) (Utilities.pxFromSp(inv.iconTextSize, dm) * scale);
- iconDrawablePaddingPx = drawablePadding;
+ iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * scale);
hotseatIconSizePx = (int) (Utilities.pxFromDp(inv.hotseatIconSize, dm) * scale);
allAppsIconSizePx = iconSizePx;
allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
allAppsIconTextSizePx = iconTextSizePx;
- cellWidthPx = iconSizePx;
+ cellWidthPx = iconSizePx + iconDrawablePaddingPx;
cellHeightPx = iconSizePx + iconDrawablePaddingPx
+ Utilities.calculateTextHeight(iconTextSizePx);
// Hotseat
- hotseatCellWidthPx = iconSizePx;
- hotseatCellHeightPx = iconSizePx;
+ hotseatCellWidthPx = cellWidthPx;
+ hotseatCellHeightPx = iconSizePx + iconDrawablePaddingPx;
if (!isVerticalBarLayout()) {
int expectedWorkspaceHeight = availableHeightPx - hotseatBarHeightPx
@@ -308,7 +310,7 @@
}
// Folder icon
- folderBackgroundOffset = -edgeMarginPx;
+ folderBackgroundOffset = -iconDrawablePaddingPx;
folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
folderIconPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding);
}
@@ -522,7 +524,7 @@
lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
lp.width = searchBarBounds.x;
lp.height = searchBarBounds.y;
- lp.topMargin = mInsets.top + edgeMarginPx;
+ lp.topMargin = mInsets.top + edgeMarginPx / 2;
searchBar.setLayoutParams(lp);
// Layout the workspace
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index ad816af..09ca5c5 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -749,7 +749,7 @@
}
private static final class IconDB extends SQLiteCacheHelper {
- private final static int DB_VERSION = 14;
+ private final static int DB_VERSION = 15;
private final static int RELEASE_VERSION = DB_VERSION +
(FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ? 0 : 1);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index bd006c7..bb32a45 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1413,7 +1413,6 @@
BubbleTextView favorite = (BubbleTextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.app_icon, parent, false);
favorite.applyFromShortcutInfo(info);
- favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);
favorite.setOnClickListener(this);
favorite.setOnFocusChangeListener(mFocusHandler);
return favorite;
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index f8742f8..3a3e13d 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -120,7 +120,7 @@
// Center the icon/folder
int cHeight = getCellContentHeight();
int cellPaddingY = (int) Math.max(0, ((lp.height - cHeight) / 2f));
- int cellPaddingX = (int) (profile.edgeMarginPx / 2f);
+ int cellPaddingX = profile.cellPaddingXPx;
child.setPadding(cellPaddingX, cellPaddingY, cellPaddingX, 0);
}
} else {
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index f66995f..d421a0e 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -111,7 +111,7 @@
* sizes (landscape vs portrait).
*/
private static class CacheDb extends SQLiteCacheHelper {
- private static final int DB_VERSION = 6;
+ private static final int DB_VERSION = 7;
private static final String TABLE_NAME = "shortcut_and_widget_previews";
private static final String COLUMN_COMPONENT = "componentName";
diff --git a/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java b/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
index 54c5bd0..3830a93 100644
--- a/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
+++ b/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
@@ -23,10 +23,12 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.view.ContextThemeWrapper;
import android.view.Gravity;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
/**
* This is a custom composite drawable that has a fixed virtual size and dynamically lays out its
@@ -36,7 +38,7 @@
public class AllAppsBackgroundDrawable extends Drawable {
/**
- * A helper class to positon and orient a drawable to be drawn.
+ * A helper class to position and orient a drawable to be drawn.
*/
protected static class TransformedImageDrawable {
private Drawable mImage;
@@ -49,9 +51,9 @@
* @param gravity If one of the Gravity center values, the x and y offset will take the width
* and height of the image into account to center the image to the offset.
*/
- public TransformedImageDrawable(Resources res, int resourceId, float xPct, float yPct,
+ public TransformedImageDrawable(Context context, int resourceId, float xPct, float yPct,
int gravity) {
- mImage = res.getDrawable(resourceId);
+ mImage = context.getDrawable(resourceId);
mXPercent = xPct;
mYPercent = yPct;
mGravity = gravity;
@@ -98,19 +100,24 @@
public AllAppsBackgroundDrawable(Context context) {
Resources res = context.getResources();
- mHand = new TransformedImageDrawable(res, R.drawable.ic_all_apps_bg_hand,
- 0.575f, 0.f, Gravity.CENTER_HORIZONTAL);
- mIcons = new TransformedImageDrawable[4];
- mIcons[0] = new TransformedImageDrawable(res, R.drawable.ic_all_apps_bg_icon_1,
- 0.375f, 0, Gravity.CENTER_HORIZONTAL);
- mIcons[1] = new TransformedImageDrawable(res, R.drawable.ic_all_apps_bg_icon_2,
- 0.3125f, 0.2f, Gravity.CENTER_HORIZONTAL);
- mIcons[2] = new TransformedImageDrawable(res, R.drawable.ic_all_apps_bg_icon_3,
- 0.475f, 0.26f, Gravity.CENTER_HORIZONTAL);
- mIcons[3] = new TransformedImageDrawable(res, R.drawable.ic_all_apps_bg_icon_4,
- 0.7f, 0.125f, Gravity.CENTER_HORIZONTAL);
mWidth = res.getDimensionPixelSize(R.dimen.all_apps_background_canvas_width);
mHeight = res.getDimensionPixelSize(R.dimen.all_apps_background_canvas_height);
+
+ context = new ContextThemeWrapper(context,
+ Themes.getAttrBoolean(context, R.attr.isMainColorDark)
+ ? R.style.AllAppsEmptySearchBackground_Dark
+ : R.style.AllAppsEmptySearchBackground);
+ mHand = new TransformedImageDrawable(context, R.drawable.ic_all_apps_bg_hand,
+ 0.575f, 0.f, Gravity.CENTER_HORIZONTAL);
+ mIcons = new TransformedImageDrawable[4];
+ mIcons[0] = new TransformedImageDrawable(context, R.drawable.ic_all_apps_bg_icon_1,
+ 0.375f, 0, Gravity.CENTER_HORIZONTAL);
+ mIcons[1] = new TransformedImageDrawable(context, R.drawable.ic_all_apps_bg_icon_2,
+ 0.3125f, 0.2f, Gravity.CENTER_HORIZONTAL);
+ mIcons[2] = new TransformedImageDrawable(context, R.drawable.ic_all_apps_bg_icon_3,
+ 0.475f, 0.26f, Gravity.CENTER_HORIZONTAL);
+ mIcons[3] = new TransformedImageDrawable(context, R.drawable.ic_all_apps_bg_icon_4,
+ 0.7f, 0.125f, Gravity.CENTER_HORIZONTAL);
}
/**
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 5794004..fc25c9a 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -60,7 +60,6 @@
import com.android.launcher3.LogDecelerateInterpolator;
import com.android.launcher3.OnAlarmListener;
import com.android.launcher3.PagedView;
-import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.UninstallDropTarget.DropTargetSource;
@@ -637,7 +636,9 @@
@Override
public void onAnimationStart(Animator animation) {
if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+ mFolderIcon.setBackgroundVisible(false);
mFolderIcon.drawLeaveBehindIfExists();
+ } else {
mFolderIcon.setVisibility(INVISIBLE);
}
@@ -790,6 +791,7 @@
mDragController.removeDropTarget(this);
clearFocus();
if (mFolderIcon != null) {
+ mFolderIcon.setBackgroundVisible(true);
mFolderIcon.setVisibility(View.VISIBLE);
if (wasAnimated) {
mFolderIcon.mBackground.animateBackgroundStroke();
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index bee0bd4..bb2d1a2 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -208,6 +208,7 @@
play(a, getAnimator(mFolder, SCALE_PROPERTY, initialScale, finalScale));
play(a, getAnimator(items, ITEMS_TEXT_COLOR_PROPERTY, Color.TRANSPARENT, finalTextColor));
play(a, getAnimator(mFolderBackground, "color", initialColor, finalColor));
+ play(a, mFolderIcon.mFolderName.createTextAlphaAnimator(!mIsOpening));
play(a, new RoundedRectRevealOutlineProvider(initialRadius, finalRadius, startRect,
endRect).createRevealAnimator(mFolder, !mIsOpening));
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 82a0733..aaa19af 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -120,6 +120,7 @@
private int mPrevTopPadding = -1;
PreviewBackground mBackground = new PreviewBackground();
+ private boolean mBackgroundIsVisible = true;
private PreviewLayoutRule mPreviewLayoutRule;
@@ -883,10 +884,17 @@
mBackground.setInvalidateDelegate(this);
}
+ public void setBackgroundVisible(boolean visible) {
+ mBackgroundIsVisible = visible;
+ invalidate();
+ }
+
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
+ if (!mBackgroundIsVisible) return;
+
if (mReferenceDrawable != null) {
computePreviewDrawingParams(mReferenceDrawable);
}
diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java
index 45c1b6a..ffcedb2 100644
--- a/src/com/android/launcher3/graphics/ShadowDrawable.java
+++ b/src/com/android/launcher3/graphics/ShadowDrawable.java
@@ -17,7 +17,6 @@
package com.android.launcher3.graphics;
import android.annotation.TargetApi;
-import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
@@ -28,7 +27,6 @@
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
@@ -111,12 +109,11 @@
@Override
public void applyTheme(Resources.Theme t) {
- if (mState.canApplyTheme()) {
- // Workaround since ColorStateList does not expose applyTheme method
- ColorDrawable cd = new ColorDrawable();
- cd.setTintList(mState.mTintColor);
- cd.applyTheme(t);
-
+ TypedArray ta = t.obtainStyledAttributes(new int[] {R.attr.isWorkspaceDarkText});
+ boolean isDark = ta.getBoolean(0, false);
+ ta.recycle();
+ if (mState.mIsDark != isDark) {
+ mState.mIsDark = isDark;
mState.mLastDrawnBitmap = null;
invalidateSelf();
}
@@ -132,21 +129,22 @@
d.setBounds(mState.mShadowSize, mState.mShadowSize,
mState.mIntrinsicWidth - mState.mShadowSize,
mState.mIntrinsicHeight - mState.mShadowSize);
- if (mState.mTintColor != null) {
- d.setTint(mState.mTintColor.getDefaultColor());
+ d.setTint(mState.mIsDark ? mState.mDarkTintColor : Color.WHITE);
+ d.draw(canvas);
+
+ // Do not draw shadow on dark theme
+ if (!mState.mIsDark) {
+ Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, BlurMaskFilter.Blur.NORMAL));
+ int[] offset = new int[2];
+ Bitmap shadow = bitmap.extractAlpha(paint, offset);
+
+ paint.setMaskFilter(null);
+ paint.setColor(mState.mShadowColor);
+ bitmap.eraseColor(Color.TRANSPARENT);
+ canvas.drawBitmap(shadow, offset[0], offset[1], paint);
+ d.draw(canvas);
}
- d.draw(canvas);
-
- Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
- paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, BlurMaskFilter.Blur.NORMAL));
- int[] offset = new int[2];
- Bitmap shadow = bitmap.extractAlpha(paint, offset);
-
- paint.setMaskFilter(null);
- paint.setColor(mState.mShadowColor);
- bitmap.eraseColor(Color.TRANSPARENT);
- canvas.drawBitmap(shadow, offset[0], offset[1], paint);
- d.draw(canvas);
if (Utilities.isAtLeastO()) {
bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
@@ -162,7 +160,6 @@
final TypedArray a = theme == null
? r.obtainAttributes(attrs, R.styleable.ShadowDrawable)
: theme.obtainStyledAttributes(attrs, R.styleable.ShadowDrawable, 0, 0);
-
try {
Drawable d = a.getDrawable(R.styleable.ShadowDrawable_android_src);
if (d == null) {
@@ -172,7 +169,8 @@
R.styleable.ShadowDrawable_android_shadowColor, Color.BLACK);
mState.mShadowSize = a.getDimensionPixelSize(
R.styleable.ShadowDrawable_android_elevation, 0);
- mState.mTintColor = a.getColorStateList(R.styleable.ShadowDrawable_android_tint);
+ mState.mDarkTintColor = a.getColor(
+ R.styleable.ShadowDrawable_darkTintColor, Color.BLACK);
mState.mIntrinsicHeight = d.getIntrinsicHeight() + 2 * mState.mShadowSize;
mState.mIntrinsicWidth = d.getIntrinsicWidth() + 2 * mState.mShadowSize;
@@ -192,8 +190,9 @@
int mShadowColor;
int mShadowSize;
- ColorStateList mTintColor;
+ int mDarkTintColor;
+ boolean mIsDark;
Bitmap mLastDrawnBitmap;
ConstantState mChildState;
@@ -209,7 +208,7 @@
@Override
public boolean canApplyTheme() {
- return mTintColor != null;
+ return true;
}
}
}
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index cc81b11..0b08ef8 100644
--- a/src/com/android/launcher3/notification/NotificationItemView.java
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -86,11 +86,16 @@
return getHeight() - footerHeight;
}
- public Animator animateHeightRemoval(int heightToRemove) {
+ public Animator animateHeightRemoval(int heightToRemove, boolean shouldRemoveFromTop) {
+ Rect startRect = new Rect(mPillRect);
Rect endRect = new Rect(mPillRect);
- endRect.bottom -= heightToRemove;
+ if (shouldRemoveFromTop) {
+ endRect.top += heightToRemove;
+ } else {
+ endRect.bottom -= heightToRemove;
+ }
return new RoundedRectRevealOutlineProvider(getBackgroundRadius(), getBackgroundRadius(),
- mPillRect, endRect, mRoundedCorners).createRevealAnimator(this, false);
+ startRect, endRect, mRoundedCorners).createRevealAnimator(this, false);
}
public void updateHeader(int notificationCount, @Nullable IconPalette palette) {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 293bab4..c5daca0 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -82,6 +82,7 @@
import java.util.Map;
import java.util.Set;
+import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -191,7 +192,7 @@
// Add dummy views first, and populate with real info when ready.
PopupPopulator.Item[] itemsToPopulate = PopupPopulator
.getItemsToPopulate(shortcutIds, notificationKeys, systemShortcuts);
- addDummyViews(itemsToPopulate, notificationKeys.size() > 1);
+ addDummyViews(itemsToPopulate, notificationKeys.size());
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
@@ -202,7 +203,7 @@
mNotificationItemView = null;
mShortcutsItemView = null;
itemsToPopulate = PopupPopulator.reverseItems(itemsToPopulate);
- addDummyViews(itemsToPopulate, notificationKeys.size() > 1);
+ addDummyViews(itemsToPopulate, notificationKeys.size());
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
@@ -252,8 +253,7 @@
systemShortcuts, systemShortcutViews));
}
- private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate,
- boolean notificationFooterHasIcons) {
+ private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate, int numNotifications) {
final Resources res = getResources();
final LayoutInflater inflater = mLauncher.getLayoutInflater();
@@ -274,6 +274,7 @@
if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) {
mNotificationItemView = (NotificationItemView) item;
+ boolean notificationFooterHasIcons = numNotifications > 1;
int footerHeight = notificationFooterHasIcons ?
res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
@@ -305,6 +306,12 @@
shortcutsItemRoundedCorners &= ~ROUNDED_TOP_CORNERS;
}
}
+ if (itemTypeToPopulate != PopupPopulator.Item.SYSTEM_SHORTCUT_ICON
+ && numNotifications > 0) {
+ // Condense shortcuts height when there are notifications.
+ item.getLayoutParams().height = res.getDimensionPixelSize(
+ R.dimen.bg_popup_item_condensed_height);
+ }
mShortcutsItemView.addShortcutView(item, itemTypeToPopulate);
if (shouldUnroundBottomCorners) {
shortcutsItemRoundedCorners &= ~ROUNDED_BOTTOM_CORNERS;
@@ -316,6 +323,9 @@
int backgroundColor = Themes.getAttrColor(mLauncher, mNotificationItemView == null
? R.attr.popupColorPrimary : R.attr.popupColorSecondary);
mShortcutsItemView.setBackgroundWithCorners(backgroundColor, shortcutsItemRoundedCorners);
+ if (numNotifications > 0) {
+ mShortcutsItemView.hideShortcuts(mIsAboveIcon, MAX_SHORTCUTS_IF_NOTIFICATIONS);
+ }
}
protected PopupItemView getItemViewAt(int index) {
@@ -639,11 +649,22 @@
ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag();
BadgeInfo badgeInfo = updatedBadges.get(PackageUserKey.fromItemInfo(originalInfo));
if (badgeInfo == null || badgeInfo.getNotificationKeys().size() == 0) {
+ // There are no more notifications, so create an animation to remove
+ // the notifications view and expand the shortcuts view (if possible).
AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet();
+ int hiddenShortcutsHeight = 0;
+ if (mShortcutsItemView != null) {
+ hiddenShortcutsHeight = mShortcutsItemView.getHiddenShortcutsHeight();
+ int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary);
+ // With notifications gone, all corners of shortcuts item should be rounded.
+ mShortcutsItemView.setBackgroundWithCorners(backgroundColor,
+ ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS);
+ removeNotification.play(mShortcutsItemView.showAllShortcuts(mIsAboveIcon));
+ }
final int duration = getResources().getInteger(
R.integer.config_removeNotificationViewDuration);
- removeNotification.play(reduceNotificationViewHeight(
- mNotificationItemView.getHeightMinusFooter(), duration));
+ removeNotification.play(adjustItemHeights(mNotificationItemView.getHeightMinusFooter(),
+ hiddenShortcutsHeight, duration));
Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0)
.setDuration(duration);
fade.addListener(new AnimatorListenerAdapter() {
@@ -665,12 +686,6 @@
showArrow.setStartDelay((long) (duration - arrowScaleDuration * 1.5));
removeNotification.playSequentially(hideArrow, showArrow);
removeNotification.start();
- if (mShortcutsItemView != null) {
- int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary);
- // With notifications gone, all corners of shortcuts item should be rounded.
- mShortcutsItemView.setBackgroundWithCorners(backgroundColor,
- ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS);
- }
return;
}
mNotificationItemView.trimNotifications(NotificationKeyData.extractKeysOnly(
@@ -689,28 +704,50 @@
mArrow, new PropertyListBuilder().scale(scale).build());
}
+ public Animator reduceNotificationViewHeight(int heightToRemove, int duration) {
+ return adjustItemHeights(heightToRemove, 0, duration);
+ }
+
/**
* Animates the height of the notification item and the translationY of other items accordingly.
*/
- public Animator reduceNotificationViewHeight(int heightToRemove, int duration) {
+ public Animator adjustItemHeights(int notificationHeightToRemove, int shortcutHeightToAdd,
+ int duration) {
if (mReduceHeightAnimatorSet != null) {
mReduceHeightAnimatorSet.cancel();
}
- final int translateYBy = mIsAboveIcon ? heightToRemove : -heightToRemove;
+ final int translateYBy = mIsAboveIcon ? notificationHeightToRemove - shortcutHeightToAdd
+ : -notificationHeightToRemove;
mReduceHeightAnimatorSet = LauncherAnimUtils.createAnimatorSet();
- mReduceHeightAnimatorSet.play(mNotificationItemView.animateHeightRemoval(heightToRemove));
+ boolean removingNotification =
+ notificationHeightToRemove == mNotificationItemView.getHeightMinusFooter();
+ boolean shouldRemoveNotificationHeightFromTop = mIsAboveIcon && removingNotification;
+ mReduceHeightAnimatorSet.play(mNotificationItemView.animateHeightRemoval(
+ notificationHeightToRemove, shouldRemoveNotificationHeightFromTop));
PropertyResetListener<View, Float> resetTranslationYListener
= new PropertyResetListener<>(TRANSLATION_Y, 0f);
+ boolean itemIsAfterShortcuts = false;
for (int i = 0; i < getItemCount(); i++) {
final PopupItemView itemView = getItemViewAt(i);
- if (!mIsAboveIcon && itemView == mNotificationItemView) {
- // The notification view is already in the right place when container is below icon.
+ if (itemIsAfterShortcuts) {
+ // Every item after the shortcuts item needs to adjust for the new height.
+ itemView.setTranslationY(itemView.getTranslationY() - shortcutHeightToAdd);
+ }
+ if (itemView == mNotificationItemView && (!mIsAboveIcon || removingNotification)) {
+ // The notification view is already in the right place.
continue;
}
ValueAnimator translateItem = ObjectAnimator.ofFloat(itemView, TRANSLATION_Y,
itemView.getTranslationY() + translateYBy).setDuration(duration);
translateItem.addListener(resetTranslationYListener);
mReduceHeightAnimatorSet.play(translateItem);
+ if (itemView == mShortcutsItemView) {
+ itemIsAfterShortcuts = true;
+ }
+ }
+ if (mIsAboveIcon) {
+ // We also need to adjust the arrow position to account for the new shortcuts height.
+ mArrow.setTranslationY(mArrow.getTranslationY() - shortcutHeightToAdd);
}
mReduceHeightAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
@@ -720,6 +757,7 @@
// container itself did not. This means the items would jump back to their
// original translation unless we update the container's translationY here.
setTranslationY(getTranslationY() + translateYBy);
+ mArrow.setTranslationY(0);
}
mReduceHeightAnimatorSet = null;
}
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index fd00105..0dc1ca0 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -52,9 +52,9 @@
*/
public class PopupPopulator {
- public static final int MAX_ITEMS = 4;
+ public static final int MAX_SHORTCUTS = 4;
@VisibleForTesting static final int NUM_DYNAMIC = 2;
- private static final int MAX_SHORTCUTS_IF_NOTIFICATIONS = 2;
+ public static final int MAX_SHORTCUTS_IF_NOTIFICATIONS = 2;
public enum Item {
SHORTCUT(R.layout.deep_shortcut, true),
@@ -77,10 +77,7 @@
boolean hasNotifications = notificationKeys.size() > 0;
int numNotificationItems = hasNotifications ? 1 : 0;
int numShortcuts = shortcutIds.size();
- if (hasNotifications && numShortcuts > MAX_SHORTCUTS_IF_NOTIFICATIONS) {
- numShortcuts = MAX_SHORTCUTS_IF_NOTIFICATIONS;
- }
- int numItems = Math.min(MAX_ITEMS, numShortcuts + numNotificationItems)
+ int numItems = Math.min(MAX_SHORTCUTS, numShortcuts) + numNotificationItems
+ systemShortcuts.size();
Item[] items = new Item[numItems];
for (int i = 0; i < numItems; i++) {
@@ -126,12 +123,12 @@
};
/**
- * Filters the shortcuts so that only MAX_ITEMS or fewer shortcuts are retained.
+ * Filters the shortcuts so that only MAX_SHORTCUTS or fewer shortcuts are retained.
* We want the filter to include both static and dynamic shortcuts, so we always
* include NUM_DYNAMIC dynamic shortcuts, if at least that many are present.
*
* @param shortcutIdToRemoveFirst An id that should be filtered out first, if any.
- * @return a subset of shortcuts, in sorted order, with size <= MAX_ITEMS.
+ * @return a subset of shortcuts, in sorted order, with size <= MAX_SHORTCUTS.
*/
public static List<ShortcutInfoCompat> sortAndFilterShortcuts(
List<ShortcutInfoCompat> shortcuts, @Nullable String shortcutIdToRemoveFirst) {
@@ -147,27 +144,27 @@
}
Collections.sort(shortcuts, SHORTCUT_RANK_COMPARATOR);
- if (shortcuts.size() <= MAX_ITEMS) {
+ if (shortcuts.size() <= MAX_SHORTCUTS) {
return shortcuts;
}
// The list of shortcuts is now sorted with static shortcuts followed by dynamic
- // shortcuts. We want to preserve this order, but only keep MAX_ITEMS.
- List<ShortcutInfoCompat> filteredShortcuts = new ArrayList<>(MAX_ITEMS);
+ // shortcuts. We want to preserve this order, but only keep MAX_SHORTCUTS.
+ List<ShortcutInfoCompat> filteredShortcuts = new ArrayList<>(MAX_SHORTCUTS);
int numDynamic = 0;
int size = shortcuts.size();
for (int i = 0; i < size; i++) {
ShortcutInfoCompat shortcut = shortcuts.get(i);
int filteredSize = filteredShortcuts.size();
- if (filteredSize < MAX_ITEMS) {
- // Always add the first MAX_ITEMS to the filtered list.
+ if (filteredSize < MAX_SHORTCUTS) {
+ // Always add the first MAX_SHORTCUTS to the filtered list.
filteredShortcuts.add(shortcut);
if (shortcut.isDynamic()) {
numDynamic++;
}
continue;
}
- // At this point, we have MAX_ITEMS already, but they may all be static.
+ // At this point, we have MAX_SHORTCUTS already, but they may all be static.
// If there are dynamic shortcuts, remove static shortcuts to add them.
if (shortcut.isDynamic() && numDynamic < NUM_DYNAMIC) {
numDynamic++;
diff --git a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
index 340a6f0..59a0386 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
@@ -16,9 +16,14 @@
package com.android.launcher3.shortcuts;
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Point;
+import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -28,7 +33,9 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
@@ -49,7 +56,10 @@
public class ShortcutsItemView extends PopupItemView implements View.OnLongClickListener,
View.OnTouchListener, LogContainerProvider {
+ private static final String TAG = "ShortcutsItem";
+
private Launcher mLauncher;
+ private LinearLayout mContent;
private LinearLayout mShortcutsLayout;
private LinearLayout mSystemShortcutIcons;
private final Point mIconShift = new Point();
@@ -57,6 +67,8 @@
private final List<DeepShortcutView> mDeepShortcutViews = new ArrayList<>();
private final List<View> mSystemShortcutViews = new ArrayList<>();
+ private int mHiddenShortcutsHeight;
+
public ShortcutsItemView(Context context) {
this(context, null, 0);
}
@@ -74,7 +86,8 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mShortcutsLayout = findViewById(R.id.deep_shortcuts);
+ mContent = findViewById(R.id.content);
+ mShortcutsLayout = findViewById(R.id.shortcuts);
}
@Override
@@ -130,17 +143,18 @@
// System shortcut icons are added to a header that is separate from the full shortcuts.
if (mSystemShortcutIcons == null) {
mSystemShortcutIcons = (LinearLayout) mLauncher.getLayoutInflater().inflate(
- R.layout.system_shortcut_icons, mShortcutsLayout, false);
+ R.layout.system_shortcut_icons, mContent, false);
View divider = LayoutInflater.from(getContext()).inflate(
R.layout.horizontal_divider, this, false);
- if (mShortcutsLayout.getChildCount() > 0) {
- mShortcutsLayout.addView(divider);
- }
- mShortcutsLayout.addView(mSystemShortcutIcons);
- if (mShortcutsLayout.getChildCount() == 1) {
- mShortcutsLayout.addView(divider);
+ boolean iconsAreBelowShortcuts = mShortcutsLayout.getChildCount() > 0;
+ if (iconsAreBelowShortcuts) {
+ mContent.addView(divider);
+ mContent.addView(mSystemShortcutIcons);
+ } else {
+ mContent.addView(divider, 0);
+ mContent.addView(mSystemShortcutIcons, 0);
}
}
mSystemShortcutIcons.addView(shortcutView, index);
@@ -172,6 +186,114 @@
}
/**
+ * Hides shortcuts until only {@param maxShortcuts} are showing. Also sets
+ * {@link #mHiddenShortcutsHeight} to be the amount of extra space that shortcuts will
+ * require when {@link #showAllShortcuts(boolean)} is called.
+ */
+ public void hideShortcuts(boolean hideFromTop, int maxShortcuts) {
+ // When shortcuts are shown, they get more space allocated to them.
+ final int oldHeight = mShortcutsLayout.getChildAt(0).getLayoutParams().height;
+ final int newHeight = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_height);
+ mHiddenShortcutsHeight = (newHeight - oldHeight) * mShortcutsLayout.getChildCount();
+
+ int numToHide = mShortcutsLayout.getChildCount() - maxShortcuts;
+ if (numToHide <= 0) {
+ return;
+ }
+ final int numShortcuts = mShortcutsLayout.getChildCount();
+ final int dir = hideFromTop ? 1 : -1;
+ for (int i = hideFromTop ? 0 : numShortcuts - 1; 0 <= i && i < numShortcuts; i += dir) {
+ View child = mShortcutsLayout.getChildAt(i);
+ if (child instanceof DeepShortcutView) {
+ mHiddenShortcutsHeight += child.getLayoutParams().height;
+ child.setVisibility(GONE);
+ int prev = i + dir;
+ if (!hideFromTop && 0 <= prev && prev < numShortcuts) {
+ // When hiding views from the bottom, make sure to hide the last divider.
+ mShortcutsLayout.getChildAt(prev).findViewById(R.id.divider).setVisibility(GONE);
+ }
+ numToHide--;
+ if (numToHide == 0) {
+ break;
+ }
+ }
+ }
+ }
+
+ public int getHiddenShortcutsHeight() {
+ return mHiddenShortcutsHeight;
+ }
+
+ /**
+ * Sets all shortcuts in {@link #mShortcutsLayout} to VISIBLE, then creates an
+ * animation to reveal the newly shown shortcuts.
+ *
+ * @see #hideShortcuts(boolean, int)
+ */
+ public Animator showAllShortcuts(boolean showFromTop) {
+ // First set all the shortcuts to VISIBLE.
+ final int numShortcuts = mShortcutsLayout.getChildCount();
+ if (numShortcuts == 0) {
+ Log.w(TAG, "Tried to show all shortcuts but there were no shortcuts to show");
+ return null;
+ }
+ final int oldHeight = mShortcutsLayout.getChildAt(0).getLayoutParams().height;
+ final int newHeight = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_height);
+ for (int i = 0; i < numShortcuts; i++) {
+ DeepShortcutView view = (DeepShortcutView) mShortcutsLayout.getChildAt(i);
+ view.getLayoutParams().height = newHeight;
+ view.requestLayout();
+ view.setVisibility(VISIBLE);
+ if (i < numShortcuts - 1) {
+ view.findViewById(R.id.divider).setVisibility(VISIBLE);
+ }
+ }
+
+ // Now reveal the newly shown shortcuts.
+ AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
+
+ if (showFromTop) {
+ // The new shortcuts pushed the original shortcuts down, but we want to animate them
+ // to that position. So we revert the translation and animate to the new.
+ animation.play(translateYFrom(mShortcutsLayout, -mHiddenShortcutsHeight));
+ } else if (mSystemShortcutIcons != null) {
+ // When adding the shortcuts from the bottom, things are a little trickier, since
+ // that means they push the icons header down. To account for this, we do the same
+ // translation trick as above, but on the header. Since this means leaving behind
+ // a blank area where the header was, we also need to clip the background.
+ animation.play(translateYFrom(mSystemShortcutIcons, -mHiddenShortcutsHeight));
+ // mPillRect is the bounds of this view before the new shortcuts were shown.
+ Rect backgroundStartRect = new Rect(mPillRect);
+ Rect backgroundEndRect = new Rect(mPillRect);
+ backgroundEndRect.bottom += mHiddenShortcutsHeight;
+ animation.play(new RoundedRectRevealOutlineProvider(getBackgroundRadius(),
+ getBackgroundRadius(), backgroundStartRect, backgroundEndRect, mRoundedCorners)
+ .createRevealAnimator(this, false));
+ }
+ for (int i = 0; i < numShortcuts; i++) {
+ // Animate each shortcut to its new height.
+ DeepShortcutView shortcut = (DeepShortcutView) mShortcutsLayout.getChildAt(i);
+ int heightDiff = newHeight - oldHeight;
+ int heightAdjustmentIndex = showFromTop ? numShortcuts - i - 1 : i;
+ int fromDir = showFromTop ? 1 : -1;
+ animation.play(translateYFrom(shortcut, heightDiff * heightAdjustmentIndex * fromDir));
+ // Make sure the text and icon stay centered in the shortcut.
+ animation.play(translateYFrom(shortcut.getBubbleText(), heightDiff / 2 * fromDir));
+ animation.play(translateYFrom(shortcut.getIconView(), heightDiff / 2 * fromDir));
+ }
+ return animation;
+ }
+
+ /**
+ * Animates the translationY of the view from the given offset to the view's current translation
+ * @return an Animator, which should be started by the caller.
+ */
+ private Animator translateYFrom(View v, int diff) {
+ float finalY = v.getTranslationY();
+ return ObjectAnimator.ofFloat(v, TRANSLATION_Y, finalY + diff, finalY);
+ }
+
+ /**
* Adds a {@link SystemShortcut.Widgets} item if there are widgets for the given ItemInfo.
*/
public void enableWidgetsIfExist(final BubbleTextView originalIcon) {
diff --git a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
index 2ad9b35..9a89b1b 100644
--- a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
+++ b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
@@ -28,7 +28,7 @@
import java.util.Collections;
import java.util.List;
-import static com.android.launcher3.popup.PopupPopulator.MAX_ITEMS;
+import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
import static com.android.launcher3.popup.PopupPopulator.NUM_DYNAMIC;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -44,18 +44,18 @@
public void testSortAndFilterShortcuts() {
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0);
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 3), 0, 3);
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 0), MAX_ITEMS, 0);
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 5), 0, MAX_ITEMS);
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 0), MAX_SHORTCUTS, 0);
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 5), 0, MAX_SHORTCUTS);
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 3),
- MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
+ MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 5),
- MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 1), MAX_ITEMS - 1, 1);
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(1, 5), 1, MAX_ITEMS - 1);
+ MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 1), MAX_SHORTCUTS - 1, 1);
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(1, 5), 1, MAX_SHORTCUTS - 1);
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 3),
- MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
+ MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 5),
- MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
+ MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
}
@Test