Merge "Replace use of java.util.HashMap with android.util.ArrayMap in AddWorkspaceItemsTask class Bug: 62466540" into ub-launcher3-dorval-polish
diff --git a/build.gradle b/build.gradle
index ef782d9..c23a299 100644
--- a/build.gradle
+++ b/build.gradle
@@ -68,6 +68,7 @@
final String SUPPORT_LIBS_VERSION = '26.0.0-SNAPSHOT'
dependencies {
compile "com.android.support:support-v4:${SUPPORT_LIBS_VERSION}"
+ compile "com.android.support:support-dynamic-animation:${SUPPORT_LIBS_VERSION}"
compile "com.android.support:recyclerview-v7:${SUPPORT_LIBS_VERSION}"
compile "com.android.support:palette-v7:${SUPPORT_LIBS_VERSION}"
compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-2'
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-ldrtl/container_fastscroll_popup_bg.xml b/res/drawable-ldrtl/container_fastscroll_popup_bg.xml
deleted file mode 100644
index 2bbf5cd..0000000
--- a/res/drawable-ldrtl/container_fastscroll_popup_bg.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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="?android:attr/colorAccent" />
- <size
- android:width="64dp"
- android:height="64dp" />
- <corners
- android:topLeftRadius="64dp"
- android:topRightRadius="64dp"
- android:bottomRightRadius="64dp" />
-</shape>
\ No newline at end of file
diff --git a/res/drawable/container_fastscroll_popup_bg.xml b/res/drawable/container_fastscroll_popup_bg.xml
deleted file mode 100644
index 3dc7680..0000000
--- a/res/drawable/container_fastscroll_popup_bg.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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="?android:attr/colorAccent" />
- <size
- android:width="64dp"
- android:height="64dp" />
- <corners
- android:topLeftRadius="64dp"
- android:topRightRadius="64dp"
- android:bottomLeftRadius="64dp" />
-</shape>
\ 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_remove_no_shadow.xml b/res/drawable/ic_remove_no_shadow.xml
index ef538a6..be7f9f3 100644
--- a/res/drawable/ic_remove_no_shadow.xml
+++ b/res/drawable/ic_remove_no_shadow.xml
@@ -21,5 +21,7 @@
android:tint="?android:attr/textColorPrimary" >
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
+ android:pathData="M13.41,12l5.29-5.29c0.39-0.39,0.39-1.02,0-1.41c-0.39-0.39-1.02-0.39-1.41,0L12,10.59L6.71,
+ 5.29c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41L10.59,12l-5.29,5.29c-0.39,0.39-0.39,1.02,
+ 0,1.41c0.39,0.39,1.02,0.39,1.41,0L12,13.41l5.29,5.29c0.39,0.39,1.02,0.39,1.41,0c0.39-0.39,0.39-1.02,0-1.41L13.41,12z"/>
</vector>
diff --git a/res/drawable/ic_setting.xml b/res/drawable/ic_setting.xml
index b0009c5..1bab189 100644
--- a/res/drawable/ic_setting.xml
+++ b/res/drawable/ic_setting.xml
@@ -20,5 +20,11 @@
android:viewportHeight="48.0">
<path
android:fillColor="?android:attr/textColorPrimary"
- android:pathData="M38.86 25.95c.08-.64 .14-1.29 .14-1.95s-.06-1.31-.14-1.95l4.23-3.31c.38-.3 .49-.84 .24-1.28l-4-6.93c-.25-.43-.77-.61-1.22-.43l-4.98 2.01c-1.03-.79-2.16-1.46-3.38-1.97L29 4.84c-.09-.47-.5-.84-1-.84h-8c-.5 0-.91 .37-.99 .84l-.75 5.3c-1.22 .51-2.35 1.17-3.38 1.97L9.9 10.1c-.45-.17-.97 0-1.22 .43l-4 6.93c-.25 .43-.14 .97 .24 1.28l4.22 3.31C9.06 22.69 9 23.34 9 24s.06 1.31 .14 1.95l-4.22 3.31c-.38 .3-.49 .84-.24 1.28l4 6.93c.25 .43 .77 .61 1.22 .43l4.98-2.01c1.03 .79 2.16 1.46 3.38 1.97l.75 5.3c.08 .47 .49 .84 .99 .84h8c.5 0 .91-.37 .99-.84l.75-5.3c1.22-.51 2.35-1.17 3.38-1.97l4.98 2.01c.45 .17 .97 0 1.22-.43l4-6.93c.25-.43 .14-.97-.24-1.28l-4.22-3.31zM24 31c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/>
+ android:pathData="M42.8,28.4l-3.88-2.9c0.06-0.5,0.08-1,0.08-1.52s-0.02-1.02-0.08-1.52l3.88-2.86c0.84-0.62,1.04-1.88,
+ 0.48-2.82l-3.2-5.52c-0.56-0.96-1.76-1.4-2.72-1l-4.28,1.82c-0.96-0.74-2.02-1.36-3.14-1.84l-0.54-4.4C29.28,4.8,28.28,4,
+ 27.18,4h-6.36c-1.1,0-2.1,0.8-2.22,1.84l-0.52,4.38c-1.14,0.48-2.2,1.1-3.16,1.84l-4.28-1.82c-0.96-0.4-2.16,0.04-2.72,
+ 1l-3.2,5.52c-0.56,0.96-0.36,2.2,0.48,2.84l3.88,2.9C9.02,22.98,9,23.48,9,24s0.02,1.02,0.08,1.52L5.2,28.4c-0.84,0.62-1.04,
+ 1.88-0.48,2.82l3.2,5.52c0.56,0.96,1.76,1.4,2.72,1l4.28-1.82c0.96,0.74,2.02,1.36,3.14,1.84l0.54,4.38C18.72,43.2,19.72,
+ 44,20.82,44h6.36c1.1,0,2.08-0.8,2.22-1.84l0.54-4.38c1.12-0.48,2.18-1.1,3.14-1.84l4.28,1.82c0.96,0.4,2.16-0.04,
+ 2.72-1l3.2-5.52C43.84,30.28,43.64,29.04,42.8,28.4z M24,31c-3.86,0-7-3.14-7-7s3.14-7,7-7s7,3.14,7,7S27.86,31,24,31z"/>
</vector>
diff --git a/res/drawable/ic_uninstall_no_shadow.xml b/res/drawable/ic_uninstall_no_shadow.xml
index 5bab422..2a86e10 100644
--- a/res/drawable/ic_uninstall_no_shadow.xml
+++ b/res/drawable/ic_uninstall_no_shadow.xml
@@ -21,5 +21,6 @@
android:tint="?android:attr/textColorPrimary" >
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
+ android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,
+ 3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4L18,4z"/>
</vector>
diff --git a/res/drawable/ic_wallpaper.xml b/res/drawable/ic_wallpaper.xml
index 30f6d1a..9e9222f 100644
--- a/res/drawable/ic_wallpaper.xml
+++ b/res/drawable/ic_wallpaper.xml
@@ -20,5 +20,10 @@
android:viewportHeight="48.0">
<path
android:fillColor="?android:attr/textColorPrimary"
- android:pathData="M8 8h14V4H8C5.79 4 4 5.79 4 8v14h4V8zm12 18l-8 10h24l-6-8-4.06 5.42L20 26zm14-9c0-1.66-1.34-3-3-3s-3 1.34-3 3 1.34 3 3 3 3-1.34 3-3zm6-13H26v4h14v14h4V8c0-2.21-1.79-4-4-4zm0 36H26v4h14c2.21 0 4-1.79 4-4V26h-4v14zM8 26H4v14c0 2.21 1.79 4 4 4h14v-4H8V26z"/>
+ android:pathData="M8,8h13c0.56,0,1-0.44,1-1V5c0-0.56-0.44-1-1-1H8C5.8,4,4,5.8,4,8v13c0,0.56,0.44,1,1,1h2c0.56,0,1-0.44,
+ 1-1V8zM18.44,27.96L12,36h24l-4.4-5.86c-0.8-1.06-2.4-1.06-3.2,0l-2.46,3.28l-4.38-5.46C20.76,26.96,19.24,26.96,18.44,27.96z M34,
+ 17c0-1.66-1.34-3-3-3s-3,1.34-3,3s1.34,3,3,3S34,18.66,34,17z M40,4H27c-0.56,0-1,0.44-1,1v2c0,0.56,0.44,1,1,1h13v13c0,
+ 0.56,0.44,1,1,1h2c0.56,0,1-0.44,1-1V8C44,5.8,42.2,4,40,4z M40,40H27c-0.56,0-1,0.44-1,1v2c0,0.56,0.44,1,1,1h13c2.2,
+ 0,4-1.8,4-4V27c0-0.56-0.44-1-1-1h-2c-0.56,0-1,0.44-1,1V40z M7,26H5c-0.56,0-1,0.44-1,1v13c0,2.2,1.8,4,4,4h13c0.56,0,1-0.44,
+ 1-1v-2c0-0.56-0.44-1-1-1H8V27C8,26.44,7.56,26,7,26z"/>
</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-land/all_apps_fast_scroller.xml b/res/layout-land/all_apps_fast_scroller.xml
new file mode 100644
index 0000000..957c331
--- /dev/null
+++ b/res/layout-land/all_apps_fast_scroller.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto">
+ <!-- Fast scroller popup -->
+ <TextView
+ android:id="@+id/fast_scroller_popup"
+ style="@style/FastScrollerPopup"
+ android:layout_alignParentEnd="true"
+ android:layout_alignTop="@+id/apps_list_view"
+ android:layout_marginEnd="-5dp" />
+
+ <com.android.launcher3.allapps.LandscapeFastScroller
+ android:id="@+id/fast_scroller"
+ android:layout_width="48dp"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignTop="@+id/apps_list_view"
+ android:layout_marginEnd="-48dp"
+ android:layout_marginTop="-8dp"
+ launcher:canThumbDetach="true" />
+
+</merge>
\ No newline at end of file
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 2e03576..2bbd76d 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -63,8 +63,8 @@
<com.android.launcher3.pageindicators.PageIndicatorCaretLandscape
android:id="@+id/page_indicator"
android:theme="@style/HomeScreenElementTheme"
- android:layout_width="@dimen/dynamic_grid_page_indicator_height"
- android:layout_height="@dimen/dynamic_grid_page_indicator_height"
+ android:layout_width="@dimen/dynamic_grid_page_indicator_size"
+ android:layout_height="@dimen/dynamic_grid_page_indicator_size"
android:layout_gravity="bottom|left"/>
<include layout="@layout/widgets_view"
diff --git a/res/layout-sw720dp/all_apps_fast_scroller.xml b/res/layout-sw720dp/all_apps_fast_scroller.xml
new file mode 100644
index 0000000..12c15cc
--- /dev/null
+++ b/res/layout-sw720dp/all_apps_fast_scroller.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto">
+ <!-- Fast scroller popup -->
+ <TextView
+ android:id="@+id/fast_scroller_popup"
+ style="@style/FastScrollerPopup"
+ android:layout_alignParentEnd="true"
+ android:layout_alignTop="@+id/apps_list_view"
+ android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
+
+ <com.android.launcher3.views.RecyclerViewFastScroller
+ android:id="@+id/fast_scroller"
+ android:layout_width="@dimen/fastscroll_width"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignTop="@+id/apps_list_view"
+ android:layout_marginEnd="@dimen/fastscroll_end_margin"
+ launcher:canThumbDetach="true" />
+
+</merge>
\ No newline at end of file
diff --git a/res/layout/add_item_confirmation_activity.xml b/res/layout/add_item_confirmation_activity.xml
index 35bcac3..6c316e6 100644
--- a/res/layout/add_item_confirmation_activity.xml
+++ b/res/layout/add_item_confirmation_activity.xml
@@ -17,57 +17,73 @@
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <TextView
- android:paddingLeft="24dp"
- android:paddingRight="24dp"
- android:paddingTop="4dp"
- android:paddingBottom="20dp"
- android:text="@string/add_item_request_drag_hint"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <ScrollView
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:clipToPadding="false">
- <FrameLayout
- android:theme="@style/WidgetContainerTheme"
- android:layout_width="match_parent"
- android:background="?android:attr/colorPrimaryDark"
- android:layout_height="wrap_content">
-
- <com.android.launcher3.dragndrop.LivePreviewWidgetCell
- android:layout_width="wrap_content"
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_weight="1"
- android:orientation="vertical"
- android:focusable="true"
- android:background="?android:attr/colorPrimaryDark"
- android:gravity="center_horizontal"
- android:id="@+id/widget_cell"
- android:layout_gravity="center_horizontal" >
+ android:orientation="vertical">
- <include layout="@layout/widget_cell_content" />
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="20dp"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:paddingTop="4dp"
+ android:text="@string/add_item_request_drag_hint" />
- </com.android.launcher3.dragndrop.LivePreviewWidgetCell>
- </FrameLayout>
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?android:attr/colorPrimaryDark"
+ android:theme="@style/WidgetContainerTheme">
+
+ <com.android.launcher3.dragndrop.LivePreviewWidgetCell
+ android:id="@+id/widget_cell"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_weight="1"
+ android:background="?android:attr/colorPrimaryDark"
+ android:focusable="true"
+ android:gravity="center_horizontal"
+ android:orientation="vertical" >
+
+ <include layout="@layout/widget_cell_content" />
+
+ </com.android.launcher3.dragndrop.LivePreviewWidgetCell>
+ </FrameLayout>
+ </LinearLayout>
+ </ScrollView>
<LinearLayout
+ style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="?android:attr/buttonBarStyle"
- android:gravity="end" >
+ android:gravity="end"
+ android:paddingBottom="4dp"
+ android:paddingEnd="12dp"
+ android:paddingStart="12dp"
+ android:paddingTop="4dp" >
<Button
+ style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@android:string/cancel"
android:onClick="onCancelClick"
- style="?android:attr/buttonBarButtonStyle" />
+ android:text="@android:string/cancel" />
<Button
+ style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/place_automatically"
android:onClick="onPlaceAutomaticallyClick"
- style="?android:attr/buttonBarButtonStyle" />
+ android:text="@string/place_automatically" />
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 09b9655..93662fc 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -16,7 +16,8 @@
<!-- The top and bottom paddings are defined in this container, but since we want
the list view to span the full width (for touch interception purposes), we
will bake the left/right padding into that view's background itself. -->
-<com.android.launcher3.allapps.AllAppsContainerView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.allapps.AllAppsContainerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/apps_view"
android:layout_width="match_parent"
@@ -39,6 +40,8 @@
android:layout_height="match_parent"
android:layout_gravity="center"
android:focusable="true"
+ android:clipToPadding="false"
+ android:clipChildren="true"
android:focusableInTouchMode="true"
android:saveEnabled="false"
android:visibility="gone">
@@ -53,17 +56,7 @@
android:clipToPadding="false"
android:overScrollMode="never"
android:descendantFocusability="afterDescendants"
- android:focusable="true"
- android:paddingStart="@dimen/container_fastscroll_thumb_max_width"
- android:paddingEnd="@dimen/container_fastscroll_thumb_max_width" />
-
- <!-- Fast scroller popup -->
- <TextView
- style="@style/FastScrollerPopup"
- android:layout_alignTop="@+id/apps_list_view"
- android:id="@+id/fast_scroller_popup"
- android:layout_alignParentEnd="true"
- android:layout_marginEnd="@dimen/container_fastscroll_popup_margin" />
+ android:focusable="true" />
<!-- Note: we are reusing/repurposing a system attribute for search layout, because of a
platform bug, which prevents using custom attributes in <include> tag -->
@@ -71,6 +64,8 @@
layout="?android:attr/keyboardLayout"
android:id="@+id/search_container" />
+ <include layout="@layout/all_apps_fast_scroller" />
+
</com.android.launcher3.allapps.AllAppsRecyclerViewContainerView>
<View
style="@style/AllAppsNavBarProtection"
diff --git a/res/layout/all_apps_discovery_item.xml b/res/layout/all_apps_discovery_item.xml
index fb1755c..728283f 100644
--- a/res/layout/all_apps_discovery_item.xml
+++ b/res/layout/all_apps_discovery_item.xml
@@ -94,8 +94,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
- android:paddingLeft="@dimen/container_fastscroll_thumb_max_width"
- android:paddingRight="@dimen/container_fastscroll_thumb_max_width"
+ android:paddingLeft="@dimen/dynamic_grid_edge_margin"
+ android:paddingRight="@dimen/dynamic_grid_edge_margin"
android:src="@drawable/all_apps_divider"
android:scaleType="fitXY"
android:focusable="false" />
diff --git a/res/layout/all_apps_discovery_loading_divider.xml b/res/layout/all_apps_discovery_loading_divider.xml
index 1ad5521..005847c 100644
--- a/res/layout/all_apps_discovery_loading_divider.xml
+++ b/res/layout/all_apps_discovery_loading_divider.xml
@@ -16,8 +16,8 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="6dp"
- android:paddingLeft="@dimen/container_fastscroll_thumb_max_width"
- android:paddingRight="@dimen/container_fastscroll_thumb_max_width">
+ android:paddingLeft="@dimen/dynamic_grid_edge_margin"
+ android:paddingRight="@dimen/dynamic_grid_edge_margin">
<ProgressBar
android:id="@+id/loadingProgressBar"
diff --git a/res/layout/all_apps_divider.xml b/res/layout/all_apps_divider.xml
index 1eaf685..8a4f646 100644
--- a/res/layout/all_apps_divider.xml
+++ b/res/layout/all_apps_divider.xml
@@ -19,8 +19,8 @@
android:layout_height="wrap_content"
android:paddingTop="@dimen/all_apps_divider_margin_vertical"
android:paddingBottom="@dimen/all_apps_divider_margin_vertical"
- android:paddingLeft="@dimen/container_fastscroll_thumb_max_width"
- android:paddingRight="@dimen/container_fastscroll_thumb_max_width"
+ android:paddingLeft="@dimen/dynamic_grid_edge_margin"
+ android:paddingRight="@dimen/dynamic_grid_edge_margin"
android:src="@drawable/all_apps_divider"
android:scaleType="fitXY"
android:focusable="false" />
\ No newline at end of file
diff --git a/res/layout/all_apps_fast_scroller.xml b/res/layout/all_apps_fast_scroller.xml
new file mode 100644
index 0000000..12c15cc
--- /dev/null
+++ b/res/layout/all_apps_fast_scroller.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto">
+ <!-- Fast scroller popup -->
+ <TextView
+ android:id="@+id/fast_scroller_popup"
+ style="@style/FastScrollerPopup"
+ android:layout_alignParentEnd="true"
+ android:layout_alignTop="@+id/apps_list_view"
+ android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
+
+ <com.android.launcher3.views.RecyclerViewFastScroller
+ android:id="@+id/fast_scroller"
+ android:layout_width="@dimen/fastscroll_width"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignTop="@+id/apps_list_view"
+ android:layout_marginEnd="@dimen/fastscroll_end_margin"
+ launcher:canThumbDetach="true" />
+
+</merge>
\ No newline at end of file
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/all_apps_search_container.xml b/res/layout/all_apps_search_container.xml
index c79360f..2528034 100644
--- a/res/layout/all_apps_search_container.xml
+++ b/res/layout/all_apps_search_container.xml
@@ -20,13 +20,24 @@
android:layout_height="@dimen/all_apps_search_bar_height"
android:layout_gravity="center|top"
android:gravity="center|bottom"
- android:saveEnabled="false">
+ android:saveEnabled="false"
+ android:paddingLeft="@dimen/dynamic_grid_edge_margin"
+ android:paddingRight="@dimen/dynamic_grid_edge_margin"
+ android:layout_marginBottom="-8dp" >
+ <!--
+ Note: The following relation should always be true so that the shadows are aligned properly
+ search_box_input.layout_marginBottom
+ == search_divider.layout_marginBottom
+ == - (search_container.layout_marginBottom)
+ >= 5dp
+ -->
<com.android.launcher3.ExtendedEditText
android:id="@+id/search_box_input"
android:layout_width="match_parent"
android:layout_height="@dimen/all_apps_search_bar_field_height"
android:layout_gravity="bottom"
+ android:layout_marginBottom="8dp"
android:background="@android:color/transparent"
android:focusableInTouchMode="true"
android:gravity="center"
@@ -39,4 +50,19 @@
android:textColor="?android:attr/textColorSecondary"
android:textColorHint="@drawable/all_apps_search_hint"
android:textSize="16sp" />
+
+ <!-- This needs to be a container with a view, to simulate a scrolling effect for the header.
+ We translate the header down, and its content up by the same amount, so that it gets
+ clipped by the parent, making it look like the divider was scrolled out of the view. -->
+ <FrameLayout
+ android:id="@+id/search_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_gravity="bottom"
+ android:layout_marginBottom="8dp" >
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@drawable/all_apps_search_divider"/>
+ </FrameLayout>
</com.android.launcher3.allapps.search.AppsSearchContainerLayout>
\ No newline at end of file
diff --git a/res/layout/all_apps_search_divider.xml b/res/layout/all_apps_search_divider.xml
deleted file mode 100644
index d2ef691..0000000
--- a/res/layout/all_apps_search_divider.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
- android:importantForAccessibility="no"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="@dimen/all_apps_divider_margin_vertical"
- android:paddingLeft="@dimen/container_fastscroll_thumb_max_width"
- android:paddingRight="@dimen/container_fastscroll_thumb_max_width"
- android:src="@drawable/all_apps_search_divider"
- android:scaleType="fitXY"
- android:focusable="false" />
\ No newline at end of file
diff --git a/res/layout/all_apps_search_market.xml b/res/layout/all_apps_search_market.xml
index 3f19b25..6f2dd3d 100644
--- a/res/layout/all_apps_search_market.xml
+++ b/res/layout/all_apps_search_market.xml
@@ -19,8 +19,8 @@
android:layout_width="match_parent"
android:layout_height="48dp"
android:gravity="center"
- android:paddingLeft="@dimen/container_fastscroll_thumb_max_width"
- android:paddingRight="@dimen/container_fastscroll_thumb_max_width"
+ android:paddingLeft="@dimen/dynamic_grid_edge_margin"
+ android:paddingRight="@dimen/dynamic_grid_edge_margin"
android:fontFamily="sans-serif-medium"
android:textSize="14sp"
android:textColor="?android:attr/colorAccent"
diff --git a/res/layout/app_icon.xml b/res/layout/app_icon.xml
index fa6eb89..52df694 100644
--- a/res/layout/app_icon.xml
+++ b/res/layout/app_icon.xml
@@ -14,4 +14,4 @@
limitations under the License.
-->
-<com.android.launcher3.BubbleTextView style="@style/BaseIcon.Workspace" />
+<com.android.launcher3.views.DoubleShadowBubbleTextView style="@style/BaseIcon.Workspace" />
diff --git a/res/layout/folder_icon.xml b/res/layout/folder_icon.xml
index ccc6b01..4093744 100644
--- a/res/layout/folder_icon.xml
+++ b/res/layout/folder_icon.xml
@@ -20,7 +20,7 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true" >
- <com.android.launcher3.BubbleTextView
+ <com.android.launcher3.views.DoubleShadowBubbleTextView
style="@style/BaseIcon.Workspace"
android:id="@+id/folder_icon_name"
android:focusable="false"
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..14ff2bd 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -18,11 +18,11 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="@style/HomeScreenElementTheme"
android:layout_width="match_parent"
- android:layout_height="@dimen/dynamic_grid_page_indicator_height">
+ android:layout_height="@dimen/dynamic_grid_page_indicator_size">
<ImageView
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/layout/user_folder.xml b/res/layout/user_folder.xml
index cde6540..4d80aac 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -24,6 +24,7 @@
<com.android.launcher3.folder.FolderPagedView
android:id="@+id/folder_content"
+ android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index 2063f32..e91f966 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -24,6 +24,7 @@
<com.android.launcher3.folder.FolderPagedView
android:id="@+id/folder_content"
+ android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml
index f1370f0..e8c6961 100644
--- a/res/layout/widgets_bottom_sheet.xml
+++ b/res/layout/widgets_bottom_sheet.xml
@@ -22,7 +22,8 @@
android:paddingTop="28dp"
android:background="?android:attr/colorPrimary"
android:elevation="@dimen/deep_shortcuts_elevation"
- android:layout_gravity="bottom">
+ android:layout_gravity="bottom"
+ android:theme="?attr/widgetsTheme">
<TextView
style="@style/TextTitle"
diff --git a/res/layout/widgets_list_row_view.xml b/res/layout/widgets_list_row_view.xml
index b6e0a0b..4cd03ce 100644
--- a/res/layout/widgets_list_row_view.xml
+++ b/res/layout/widgets_list_row_view.xml
@@ -41,7 +41,7 @@
android:singleLine="true"
android:textColor="?android:attr/textColorPrimary"
android:textSize="16sp"
- launcher:customShadows="false"
+ android:textAlignment="viewStart"
launcher:deferShadowGeneration="true"
launcher:iconDisplay="widget_section"
launcher:iconSizeOverride="@dimen/widget_section_icon_size"
diff --git a/res/layout/widgets_view.xml b/res/layout/widgets_view.xml
index 476901d..4f3c7c8 100644
--- a/res/layout/widgets_view.xml
+++ b/res/layout/widgets_view.xml
@@ -23,25 +23,25 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="afterDescendants"
- launcher:revealBackground="@drawable/round_rect_primary"
- android:theme="@style/WidgetContainerTheme">
+ android:theme="?attr/widgetsTheme"
+ launcher:revealBackground="@drawable/round_rect_primary">
<View
android:id="@+id/reveal_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
- android:focusable="false"
android:elevation="2dp"
+ android:focusable="false"
android:visibility="invisible" />
<FrameLayout
android:id="@+id/main_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:layout_gravity="center"
android:elevation="15dp"
- android:visibility="gone"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:visibility="gone">
<com.android.launcher3.widget.WidgetsRecyclerView
android:id="@+id/widgets_list_view"
@@ -50,17 +50,24 @@
<!-- Fast scroller popup -->
<TextView
- style="@style/FastScrollerPopup"
android:id="@+id/fast_scroller_popup"
+ style="@style/FastScrollerPopup"
android:layout_gravity="top|end"
- android:layout_marginEnd="@dimen/container_fastscroll_popup_margin" />
+ android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
<ProgressBar
+ android:id="@+id/loader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:id="@+id/loader"
android:layout_gravity="center" />
- </FrameLayout>
+ <com.android.launcher3.views.RecyclerViewFastScroller
+ android:id="@+id/fast_scroller"
+ android:layout_width="@dimen/fastscroll_width"
+ android:layout_height="match_parent"
+ android:layout_gravity="end"
+ android:layout_marginEnd="@dimen/fastscroll_end_margin" />
+
+ </FrameLayout>
</com.android.launcher3.widget.WidgetsContainerView>
\ No newline at end of file
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 78873b2..fe00d7a 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Laat toe dat tuisskerm gedraai word"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer foon gedraai word"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Huidige vertooninstelling laat nie rotasie toe nie"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Kennisgewingkolle"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aan"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Af"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Voeg ikoon by tuisskerm"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Vir nuwe programme"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 8515625..aebb428 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ስልኩ ሲዞር"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"የአሁኑ የማሳያ ቅንብር ማሽከርከርን አይፈቅድም"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"የማሳወቂያ ነጥቦች"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"በርቷል"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ጠፍቷል"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"አዶ ወደ የመነሻ ማያ ገጽ አክል"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ለአዲስ መተግበሪያዎች"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index dd64a18..a45e40e 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"السماح بتدوير الشاشة الرئيسية"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"عند تدوير الهاتف"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"لا يسمح إعداد العرض الحالي بالتدوير"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"نقاط الإشعارات"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"قيد التشغيل"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"قيد الإيقاف"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"إضافة رمز إلى الشاشة الرئيسية"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"للتطبيقات الجديدة"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
index 2a275e5..a8791b7 100644
--- a/res/values-az-rAZ/strings.xml
+++ b/res/values-az-rAZ/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Əsas ekranın firlanmağına icazə verin"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon çevrilən zaman"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cari Ekran ayarı fırlatmağa icazə vermir"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Bildiriş nişanı"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktiv"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Deaktiv"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Əsas ekrana ikona əlavə edin"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni tətbiqlər üçün"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 2484051..cb296f4 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotaciju početnog ekrana"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon rotira"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Aktuelno podešavanje prikaza ne dozvoljava rotaciju"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Tačke za obaveštenja"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Uključeno"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Isključeno"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni ekran"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-be-rBY/strings.xml b/res/values-be-rBY/strings.xml
index 8a05ff0..0a055a4 100644
--- a/res/values-be-rBY/strings.xml
+++ b/res/values-be-rBY/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Дазволіць паварот галоўнага экрана"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Пры павароце тэлефона"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Бягучая налада дысплэя не прадугледжвае паварот"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Значкі апавяшчэнняў"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Уключана"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Выключана"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Дадаць значок на Галоўны экран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Для новых праграм"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 591f823..d5df3f2 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешаване на завъртането на началния екран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"При завъртане на телефона"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Текущата настройка на екрана не разрешава завъртане"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Точки за известия"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Включено"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Изключено"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавяне на икона към началния екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови приложения"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 4dbdf72..d4c5210 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"হোমস্ক্রীন ঘোরানোর অনুমতি দিন"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"যখন ফোনটি ঘোরানো হয়"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"বর্তমান প্রদর্শনের সেটিংস ঘোরানোর মঞ্জুরি দেয় না"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"বিজ্ঞপ্তি ডট"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"চালু হয়েছে"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"বন্ধ আছে"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"হোম স্ক্রিনে আইকন যোগ করুন"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন অ্যাপ্লিকেশানগুলির জন্যে"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"আইকনের আকৃতি পরিবর্তন করুন"</string>
diff --git a/res/values-bs-rBA/strings.xml b/res/values-bs-rBA/strings.xml
index 17a64c6..d91106b 100644
--- a/res/values-bs-rBA/strings.xml
+++ b/res/values-bs-rBA/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotiranje početnog ekrana"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon zarotira"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Trenutne postavke ekrana ne dozvoljavaju rotiranje"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Tačke za obavještenja"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Uključeno"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Isključeno"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodajte ikonu na početni ekran"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 5e26f72..88b02bb 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permet la rotació de la pantalla d\'inici"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"En girar el telèfon"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"La configuració actual de la pantalla no permet la rotació"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Punts de notificació"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activada"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivada"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Afegeix la icona a la pantalla d\'inici"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per a les aplicacions noves"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 5b582aa..1a80e39 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Povolit otáčení plochy"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Při otočení telefonu"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Aktuální nastavení displeje neumožňuje otáčení"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Puntíky s oznámeními"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Zapnuto"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Vypnuto"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Přidat ikonu na plochu"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pro nové aplikace"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 2b33416..17316b3 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillad rotation af startskærmen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Den aktuelle indstilling for visning tillader ikke rotation"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Underretningscirkler"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Til"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Fra"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Føj ikon til startskærmen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apps"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 78921b1..72f7399 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Drehung des Startbildschirms zulassen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Bei Drehung des Smartphones"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Die aktuelle \"Display\"-Einstellung verhindert eine Drehung der Anzeige"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"App-Benachrichtigungspunkte"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktiviert"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Deaktiviert"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Symbol zu Startbildschirm hinzufügen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Für neue Apps"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index dbb50e2..406101c 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Όταν το τηλέφωνο περιστρέφεται"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Η τρέχουσα ρύθμιση οθόνης δεν επιτρέπει την περιστροφή"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Κουκκίδες ειδοποίησης"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Ενεργή"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Ανενεργή"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Προσθήκη εικονιδίου στην Αρχική οθόνη"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Για νέες εφαρμογές"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index b19629a..4e0ba03 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index b19629a..4e0ba03 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index b19629a..4e0ba03 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index d7059ef..bef4757 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir la rotación de la pantalla principal"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"La configuración actual no permite la rotación de la pantalla"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Puntos de notificación"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activada"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivada"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Agregar ícono a la pantalla principal"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para nuevas apps"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index c9765e4..e49ac3f 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotación de la pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"La configuración de pantalla actual no permite girar la pantalla"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Puntos de notificación"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activada"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivada"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Añadir icono a la pantalla de inicio"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para nuevas aplicaciones"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 73420d3..f5ea456 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Luba avaekraani pööramine"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kui telefoni pööratakse"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Praegune kuvaseade ei luba pööramist"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Märguandetäpid"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Sees"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Väljas"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisa ikoon avaekraanile"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uute rakenduste puhul"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index 07ffe7f..59fc221 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Baimendu hasierako pantaila biratzea"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefonoa biratzen denean"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Uneko pantaila-ezarpenak ez du onartzen ikuspegia biratzea"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Jakinarazteko biribiltxoak"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktibatuta"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desaktibatuta"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Gehitu ikonoa hasierako pantailan"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Aplikazio berrietan"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 4ed446e..4edc4e7 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"امکان دادن به چرخش صفحه اصلی"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"وقتی تلفن چرخانده میشود"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"تنظیم نمایشگر کنونی اجازه چرخش نمیدهد"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"نقطههای اعلان"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"روشن"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"خاموش"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"افزودن نماد به صفحه اصلی"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"برای برنامههای جدید"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 559340a..f24cbae 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Salli aloitusnäytön kiertäminen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kun puhelinta kierretään"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Nykyiset näyttöasetukset eivät salli näytön kiertämistä."</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Pistemerkit"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Käytössä"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Pois käytöstä"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisää kuvake aloitusruutuun"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uusille sovelluksille"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index c96381e..5a3bd54 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Le mode d\'affichage actuel ne permet pas le pivotement"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Points de notification"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activé"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Désactivé"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ajouter l\'icône à l\'écran d\'accueil"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pour les nouvelles applications"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index bd1d3de..2897af0 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Le paramètre d\'affichage actuel n\'autorise pas la rotation."</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Pastilles de notification"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activé"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Désactivé"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ajouter l\'icône à l\'écran d\'accueil"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pour les nouvelles applications"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index 68f5a33..9211ba1 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir xirar a pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Ao xirar o teléfono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A configuración de visualización actual non permite xirar a pantalla"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Puntos de notificacións"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activado"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivado"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engadir icona á pantalla de inicio"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicacións"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
index b037d14..b491e42 100644
--- a/res/values-gu-rIN/strings.xml
+++ b/res/values-gu-rIN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"વર્તમાન પ્રદર્શન સેટિંગ ફેરવવાની પરવાનગી આપતી નથી"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"સૂચના બિંદુઓ"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ચાલુ"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"બંધ"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"હોમ સ્ક્રીન પર આઇકન ઉમેરો"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"નવી ઍપ્લિકેશનો માટે"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"આઇકનનો આકાર બદલો"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index a234e2a..371f6b7 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"होमस्क्रीन घुमाने की अनुमति दें"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फ़ोन घुुमाए जाने पर"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"वर्तमान प्रदर्शन सेटिंग घुमाने की अनुमति नहीं देती"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"नोटिफ़िकेशन बिंदु"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"चालू"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"बंद"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"होम स्क्रीन में आइकन जोड़ें"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नए ऐप्लिकेशन के लिए"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 8e8283e..0912677 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Dopusti zakretanje početnog zaslona"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon zakrene"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Trenutačna postavka zaslona ne dopušta zakretanje"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Točke obavijesti"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Uključeno"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Isključeno"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni zaslon"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 32c8661..3ffd508 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"A kezdőképernyő elforgatásának engedélyezése"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"A telefon elforgatásakor"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A jelenlegi kijelzőbeállítások nem teszik lehetővé az elforgatást"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Értesítési pöttyök"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Bekapcsolva"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Kikapcsolva"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ikon hozzáadása a kezdőképernyőhöz"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Új alkalmazásoknál"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index af75e69..1646f9e 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Թույլ տալ հիմնական էկրանի պտտումը"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Հեռախոսը պտտելու դեպքում"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Ցուցադրման ընթացիկ կարգավորումներն արգելում են պտտումը"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Ծանուցման կետեր"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Միացված է"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Անջատված է"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ավելացնել պատկերակը Հիմնական էկրանին"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Նոր հավելվածների համար"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 0d87f26..5634963 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Izinkan layar Utama diputar"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Saat ponsel diputar"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Setelan Tampilan Saat Ini tidak memungkinkan putaran"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Titik notifikasi"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktif"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Nonaktif"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon ke layar Utama"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk aplikasi baru"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 0f834df..853cd3b 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Leyfa snúning fyrir heimaskjá"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Þegar símanum er snúið"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Núverandi skjástilling leyfir ekki snúning"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Tilkynningapunktar"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Kveikt"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Slökkt"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bæta tákni á heimaskjáinn"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Fyrir ný forrit"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index f3c8880..8af098d 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Consenti rotazione della schermata Home"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Con il telefono ruotato"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"L\'impostazione corrente del display non consente la rotazione"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Indicatori notifica"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Attiva"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Non attiva"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Aggiungi icone alla schermata Home"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per le nuove app"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 3112760..2425254 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"אפשרות סיבוב של מסך דף הבית"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"כאשר הטלפון מסובב"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"הגדרת התצוגה הנוכחית אינה מאפשרת סיבוב"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"סימני הודעות"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"מופעלת"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"כבויה"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"הוספת סמל במסך דף הבית"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"לאפליקציות חדשות"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 2564372..cb5fa15 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ホーム画面の回転を許可"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"スマートフォンが回転したとき"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"現在の [ディスプレイ] 設定では回転を使用できません"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"通知ドット"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ON"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"OFF"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ホーム画面にアイコンを追加"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"新しいアプリをダウンロードしたときに"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 7b9c2dd..2634cdf 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ტელეფონის შეტრიალებისას"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ბრუნვა დაუშვებელია ჩვენების მიმდინარე პარამეტრებით"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"შეტყობინების ნიშნულები"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ჩართული"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"გამორთული"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ხატულას მთავარ ეკრანზე დამატება"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ახალი აპებისთვის"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index e04eaa1..66766b6 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Негізгі экранның бұрылуына рұқсат ету"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бұрылғанда"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Экранның ағымдағы параметрі айналуға рұқсат бермейді"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Хабарландыру белгілері"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Қосулы"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Өшірулі"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Негізгі экранға белгіше енгізу"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңа қолданбаларға арналған"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 350672e..ee44302 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ការកំណត់អេក្រង់បច្ចុប្បន្នមិនអនុញ្ញាតការបង្វិលទេ"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"ស្លាកជូនដំណឹង"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"បើក"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"បិទ"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"បញ្ចូលរូបតំណាងទៅអេក្រង់ដើម"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"សម្រាប់កម្មវិធីថ្មី"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 12fdfbd..6c89b7b 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ಫೋನ್ ತಿರುಗಿಸಿದಾಗ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ಪ್ರಸ್ತುತ ಪ್ರದರ್ಶನ ಸೆಟ್ಟಿಂಗ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"ಅಧಿಸೂಚನೆ ಡಾಟ್ಗಳು"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ಆನ್"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ಆಫ್"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ಮುಖಪುಟದ ಪರದೆಗೆ ಐಕಾನ್ ಸೇರಿಸಿ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"ಐಕಾನ್ ಆಕಾರವನ್ನು ಬದಲಿಸಿ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 15ed16a..26535f0 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"홈 화면 회전 허용"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"휴대전화 회전 시"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"현재 표시 설정에는 회전 기능이 허용되지 않습니다."</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"알림 표시 점"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"사용"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"사용 안함"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"홈 화면에 아이콘 추가"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"새로 설치한 앱에 적용"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 044f76d..cc15f04 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды айлантууга уруксат берүү"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон айланганда"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Экранды айлантуу параметри өчүрүлгөн"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Эскертме белгилери"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Күйүк"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Өчүк"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Башкы экранга сүрөтчө кошуу"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңы колдонмолор үчүн"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 3915759..08073ce 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -4,9 +4,9 @@
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.
@@ -15,6 +15,24 @@
-->
<resources>
-<!-- Container -->
- <item name="container_margin" format="fraction" type="fraction">12%</item>
+ <!-- Container -->
+ <item name="container_margin" format="fraction" type="fraction">12%</item>
+
+ <!-- Fast scroll -->
+ <dimen name="fastscroll_popup_width">58dp</dimen>
+ <dimen name="fastscroll_popup_height">48dp</dimen>
+ <dimen name="fastscroll_popup_padding">10dp</dimen>
+ <dimen name="fastscroll_popup_text_size">24dp</dimen>
+
+ <!-- Dynamic grid -->
+ <dimen name="dynamic_grid_overview_bar_item_width">120dp</dimen>
+ <dimen name="dynamic_grid_page_indicator_size">24dp</dimen>
+ <dimen name="dynamic_grid_icon_drawable_padding">8dp</dimen>
+ <dimen name="dynamic_grid_cell_padding_x">8dp</dimen>
+
+ <!-- Hotseat -->
+ <dimen name="dynamic_grid_hotseat_land_left_nav_bar_right_padding">18dp</dimen>
+ <dimen name="dynamic_grid_hotseat_land_right_nav_bar_right_padding">6dp</dimen>
+ <dimen name="dynamic_grid_hotseat_land_left_nav_bar_gutter_width">24dp</dimen>
+ <dimen name="dynamic_grid_hotseat_land_right_nav_bar_gutter_width">32dp</dimen>
</resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 3a0fb8c..0b29434 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ເມື່ອໝຸນໂທລະສັບ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ການຕັ້ງຄ່າສະແດງຜົນປັດຈຸບັນບໍ່ອະນຸຍາດໃຫ້ໝຸນໄດ້"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"ຈຸດການແຈ້ງເຕືອນ"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ເປີດ"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ປິດ"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ເພີ່ມໄອຄອນໃສ່ໜ້າຈໍຫຼັກ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ສຳລັບແອັບໃໝ່"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 98955c0..945cbf6 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Leisti pasukti pagrindinį ekraną"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kai telefonas pasukamas"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Naudojant dabartinį pateikties nustatymą neleidžiama pasukti"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Pranešimų taškai"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Įjungta"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Išjungta"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pridėti piktogr. prie pagrindinio ekrano"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Skirta naujoms programoms"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 0d6be8e..e3c3482 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Atļaut sākuma ekrāna pagriešanu"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Pagriežot tālruni"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Pašreizējā displeja iestatījumā nav atļauta pagriešana."</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Paziņojumu punkti"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Ieslēgts"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Izslēgts"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pievienot ikonu sākuma ekrānā"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Jaunām lietotnēm"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 89649af..abd1d35 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволете ротација на Почетниот екран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Кога телефонот се ротира"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Тековната поставка на Екранот не дозволува ротација"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Точки за известување"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Вклучено"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Исклучено"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додајте икона на почетниот екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови апликации"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 316dd1f..bad7e48 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ഫോൺ തിരിച്ച നിലയിലായിരിക്കുമ്പോൾ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"നിലവിലെ ഡിസ്പ്ലേ ക്രമീകരണം തിരിക്കൽ അനുവദിക്കുന്നില്ല"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"അറിയിപ്പ് ഡോട്ടുകൾ"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ഓൺ"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ഓഫ്"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ഹോം സ്ക്രീനിലേക്ക് ഐക്കൺ ചേർക്കുക"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"പുതിയ ആപ്പുകൾക്ക്"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"ഐക്കണിന്റെ ആകാരം മാറ്റുക"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index fd36e80..264e55a 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Утсыг эргүүлсэн үед"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Дэлгэцийн одоогийн тохиргоогоор эргүүлэх боломжгүй"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Мэдэгдлийн цэг"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Асаалттай"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Унтраалттай"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Нүүр хуудаст дүрс тэмдэг нэмэх"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Шинэ аппад зориулсан"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index 0a03108..b23ea96 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"मुख्यस्क्रीन फिरविण्यास अनुमती द्या"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फोन फिरविला जातो तेव्हा"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"वर्तमान प्रदर्शन सेटिंग फिरविण्यास परवानगी देत नाही"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"सूचना बिंदू"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"चालू"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"बंद"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"मुख्य स्क्रीनवर चिन्ह जोडा"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नवीन अॅप्ससाठी"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"चिन्हाचा आकार बदला"</string>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index ee242e9..0928b7d 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Benarkan putaran Skrin Utama"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Apabila telefon diputar"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Tetapan Paparan semasa tidak membenarkan putaran"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Titik pemberitahuan"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Hidup"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Mati"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon pada Skrin Utama"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk apl baharu"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index ae1ba71..a4648b1 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ဖုန်းကိုလှည့်ထားစဉ်"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"လက်ရှိ မြင်ကွင်းဆက်တင်တွင် မြင်ကွင်းကို လှည့်ခွင့်မပေးပါ"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"အကြောင်းကြားချက်အမှတ်အသားများ"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ဖွင့်ထားသည်"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ပိတ်ထားသည်"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"အက်ပ်အသစ်များအတွက်"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 092c5e1..2b776d6 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillat rotasjon av startskjermen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Med den nåværende skjerminnstillingen støttes ikke rotasjon"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Varselsprikker"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"På"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Av"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Legg til ikon på startsiden"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apper"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index e81bedd..558b6cf 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"गृह स्क्रिनलाई घुम्ने अनुमति दिनुहोस्"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फोनलाई घुमाइँदा"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"हालको प्रदर्शन सम्बन्धी सेटिङले घुमाउने सुविधालाई अनुमति दिँदैन"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"सूचनाको प्रतीक जनाउने थोप्लोहरू"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"सक्रिय छ"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"निष्क्रिय छ"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"गृह स्क्रिनमा आइकन थप्नुहोस्"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नयाँ अनुप्रयोगका लागि"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"आइकनको आकार परिवर्तन गर्नुहोस्"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 9a1d38a..0180bb4 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Draaien van startscherm toestaan"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer de telefoon gedraaid is"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Huidige scherminstelling staat draaien niet toe"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Meldingsstipjes"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aan"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Uit"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pictogram toevoegen aan startscherm"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Voor nieuwe apps"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
index ee0b5d2..05fe509 100644
--- a/res/values-pa-rIN/strings.xml
+++ b/res/values-pa-rIN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ਮੁੱਖ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ਜਦੋਂ ਫ਼ੋਨ ਘੁੰਮਾਇਆ ਜਾਂਦਾ ਹੈ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ਵਰਤਮਾਨ ਡਿਸਪਲੇ ਸੈਟਿੰਗ ਘੁੰਮਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੰਦੀ ਹੈ"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"ਸੂਚਨਾ ਬਿੰਦੂ"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ਚਾਲੂ"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ਬੰਦ"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ਮੁੱਖ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰਤੀਕ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ਨਵੀਆਂ ਐਪਾਂ ਲਈ"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"ਆਈਕਨ ਦੀ ਆਕ੍ਰਿਤੀ ਬਦਲੋ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 23d8833..f8a7f66 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Zezwalaj na obrót ekranu głównego"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Po obróceniu telefonu"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Obecne ustawienia wyświetlania nie pozwalają na obrót ekranu"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Plakietki z powiadomieniami"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Włączono"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Wyłączono"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonę do ekranu głównego"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"W przypadku nowych aplikacji"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index e03f38c..5c37eb8 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação do ecrã principal"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o telemóvel é rodado"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A definição de visualização atual não permite a rotação"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Pontos de notificação"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Ativada"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desativada"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adicionar ícone ao ecrã principal"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicações"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 9e997bd..fd24066 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação da tela inicial"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o smartphone for girado"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A configuração atual de exibição não permite rotação"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Pontos de notificação"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Ativado"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desativado"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adicionar ícone à tela inicial"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novos apps"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 33b06de..e7b8144 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permiteți rotirea ecranului de pornire"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Când telefonul este rotit"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Setarea actuală a afișajului nu permite rotirea"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Puncte de notificare"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activat"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Dezactivat"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adaugă pictograme în ecranul de pornire"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pentru aplicații noi"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index d3fbcc9..07ff761 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешить поворачивать главный экран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Когда телефон повернут"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"В настройках отключен поворот экрана"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Значки уведомлений"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ВКЛ"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ВЫКЛ"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавлять значки"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Добавлять значки установленных приложений на главный экран."</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index eaa2c2e..3b0425e 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"දුරකථනය කරකවන විට"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"වත්මන් සංදර්ශක සැකසීම් කරකැවීමට සහාය නොදක්වයි"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"දැනුම්දීම් තිත්"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ක්රියාත්මකයි"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ක්රියාවිරහිතයි"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"මුල් පිටු තිරය වෙත අයිකනය එක් කරන්න"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"නව යෙදුම් සඳහා"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index f0e11a3..b7999f4 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Povoliť otáčanie plochy"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Pri otočení telefónu"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Aktuálne nastavenie obrazovky nepovoľuje otáčanie"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Bodky upozornení"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Zapnuté"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Vypnuté"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pridať ikonu na plochu"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pri inštalácii novej aplikácie"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 9553eb5..927b389 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Omogočanje sukanja začetnega zaslona"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Ko se telefon zasuka"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Trenutna nastavitev zaslona ne dovoljuje sukanja"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Obvestilne pike"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Vklopljeno"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Izklopljeno"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikono na začetni zaslon"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
index 6ced0cd..1400557 100644
--- a/res/values-sq-rAL/strings.xml
+++ b/res/values-sq-rAL/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Lejo rrotullimin e ekranit kryesor"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kur telefoni rrotullohet"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cilësimi aktuali i afishimit nuk lejon rrotullimin"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Pikat e njoftimeve"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktiv"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Joaktiv"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Shto ikonë në ekranin bazë"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Për aplikacionet e reja"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 58dc881..2cfaee6 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволи ротацију почетног екрана"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Када се телефон ротира"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Актуелно подешавање приказа не дозвољава ротацију"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Тачке за обавештења"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Укључено"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Искључено"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додај икону на почетни екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нове апликације"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 4ff1751..aa6e99a 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillåt rotering av startskärmen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"När mobilen vrids"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Rotering tillåts inte i de nuvarande skärminställningarna"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Aviseringsprickar"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"På"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Av"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lägg till ikonen på startskärmen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"För nya appar"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 32cade6..3b6d373 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -78,12 +78,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Ruhusu kuzungusha skrini ya Kwanza"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Simu inapozungushwa"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Mipangilio ya sasa ya sehemu ya Onyesho hairuhusu kuzungusha"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Vitone vya arifa"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Imewashwa"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Imezimwa"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ongeza aikoni kwenye Skrini ya kwanza"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Kwa ajili ya programu mpya"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 358d9b6..e836d7d 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -15,10 +15,16 @@
-->
<resources>
-<!-- All Apps -->
+ <!-- All Apps -->
<dimen name="all_apps_button_scale_down">8dp</dimen>
<dimen name="all_apps_search_bar_height">54dp</dimen>
<dimen name="all_apps_empty_search_message_top_offset">64dp</dimen>
<dimen name="all_apps_empty_search_bg_top_offset">180dp</dimen>
+ <!-- Fast scroll -->
+ <dimen name="fastscroll_popup_width">75dp</dimen>
+ <dimen name="fastscroll_popup_height">62dp</dimen>
+ <dimen name="fastscroll_popup_padding">13dp</dimen>
+ <dimen name="fastscroll_popup_text_size">32dp</dimen>
+
</resources>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index 7feab16..be8e82d 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"முகப்புத் திரை சுழற்சியை அனுமதி"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"மொபைலைச் சுழற்றும் போது"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"தற்போதைய திரை அமைப்பு சுழற்றுவதை அனுமதிக்கவில்லை"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"அறிவிப்புப் புள்ளிகள்"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"இயக்கப்பட்டுள்ளது"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"முடக்கப்பட்டுள்ளது"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"முகப்புத் திரையில் ஐகானைச் சேர்"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"புதிய பயன்பாடுகளுக்கு"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index 1464347..15f3de7 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ఫోన్ను తిప్పినప్పుడు"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ప్రస్తుత డిస్ప్లే సెట్టింగ్ భ్రమణాన్ని అనుమతించలేదు"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"నోటిఫికేషన్ డాట్లు"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"ఆన్"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ఆఫ్"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"హోమ్ స్క్రీన్కి చిహ్నాన్ని జోడించు"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"కొత్త అనువర్తనాల కోసం"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"చిహ్న ఆకారాన్ని మార్చు"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 687f7c0..e03931e 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"อนุญาตให้หมุนหน้าจอหลัก"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"เมื่อหมุนโทรศัพท์"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"การตั้งค่าการแสดงผลปัจจุบันไม่อนุญาตให้มีการหมุน"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"จุดการแจ้งเตือน"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"เปิด"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"ปิด"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"เพิ่มไอคอนในหน้าจอหลัก"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"สำหรับแอปใหม่"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 3b68a9e..12bc013 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Payagan ang pag-rotate ng Home screen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kailan maro-rotate ang telepono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Hindi pinahihintulutan ng kasalukuyang setting ng Display ang pag-rotate"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Mga notification dot"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Naka-on"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Naka-off"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Idagdag ang icon sa Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para sa mga bagong app"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index d6444de..b245bff 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Ana ekranı döndürmeye izin ver"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon döndürüldüğünde"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Mevcut Ekran ayarı, döndürmeye izin vermiyor"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Bildirim noktaları"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Açık"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Kapalı"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ana ekrana simge ekle"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni uygulamalar için"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index d9c7e1b..8d33910 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволити обертання головного екрана"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Коли телефон обертається"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Поточні налаштування дисплея не підтримують обертання"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Значки сповіщень"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Увімкнено"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Вимкнено"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додати значок на головний екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Для нових додатків"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index ed73623..84966b2 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ہوم اسکرین گھمانے کی اجازت دیں"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"جب فون گھمایا جاتا ہے"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"موجودہ ڈسپلے ترتیب گھمانے کی اجازت نہیں دیتی"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"اطلاعاتی ڈاٹس"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"آن"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"آف"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"آئیکن کو ہوم اسکرین میں شامل کریں"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"نئی ایپس کیلئے"</string>
<string name="icon_shape_override_label" msgid="2977264953998281004">"آئیکن کی شکل تبدیل کریں"</string>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index c5dfc51..a4725db 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Asosiy ekranni aylantirishga ruxsat berish"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon burilganda"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Ekran sozlamalariga ko‘ra uni aylantirib bo‘lmaydi"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Bildirishnoma nuqtalari"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Yoniq"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"O‘chiq"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bosh ekranga ikonka qo‘shish"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-v26/styles.xml b/res/values-v26/styles.xml
index cb18409..fd6fc4d 100644
--- a/res/values-v26/styles.xml
+++ b/res/values-v26/styles.xml
@@ -21,6 +21,10 @@
<style name="WidgetContainerTheme" parent="@android:style/Theme.DeviceDefault.Settings">
<item name="android:colorEdgeEffect">?android:attr/textColorSecondary</item>
</style>
+ <style name="WidgetContainerTheme.Dark" parent="LauncherThemeDark">
+ <item name="android:colorEdgeEffect">?android:attr/textColorSecondary</item>
+ <item name="android:colorPrimaryDark">#616161</item> <!-- Gray 700 -->
+ </style>
<!-- From O and above, we show a dark nav bar in all-apps -->
<style name="AllAppsNavBarProtection">
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index c299c78..f6cb8f2 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Cho phép xoay Màn hình chính"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Khi xoay điện thoại"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cài đặt Hiển thị hiện tại không cho phép xoay"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Dấu chấm thông báo"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Đang bật"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Đã tắt"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Thêm biểu tượng vào màn hình chính"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Cho ứng dụng mới"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index d3bfd1b..5dcef74 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"允许旋转主屏幕"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"手机旋转时"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"当前的显示设置不允许旋转设备"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"通知圆点"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"开启"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"关闭"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"将图标添加到主屏幕"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"适用于新应用"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 7935573..2bbc160 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"允許主畫面旋轉"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"「目前顯示屏」設定不允許旋轉"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"通知圓點"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"開啟"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"關閉"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"將圖示加到主畫面"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"適用於新安裝的應用程式"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 283e83e..f1605f6 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"允許旋轉主螢幕"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"目前的顯示設定不允許旋轉畫面"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"通知圓點"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"已啟用"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"已停用"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"將圖示加到主螢幕"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"適用於新安裝的應用程式"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 8502379..12d14bd 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -76,12 +76,9 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Vumela ukuphendukiswa kwesikrini sasekhaya"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Uma ifoni iphendukiswa"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Isilungiselelo sesiboniso samanje asivumeli ukuzungezisa"</string>
- <!-- no translation found for icon_badging_title (874121399231955394) -->
- <skip />
- <!-- no translation found for icon_badging_desc_on (2627952638544674079) -->
- <skip />
- <!-- no translation found for icon_badging_desc_off (5503319969924580241) -->
- <skip />
+ <string name="icon_badging_title" msgid="874121399231955394">"Amachashazi esaziso"</string>
+ <string name="icon_badging_desc_on" msgid="2627952638544674079">"Kuvuliwe"</string>
+ <string name="icon_badging_desc_off" msgid="5503319969924580241">"Kuvaliwe"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engeza isithonjana eskrinini sasekhaya"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Kwezinhlelo zokusebenza ezintsha"</string>
<!-- no translation found for icon_shape_override_label (2977264953998281004) -->
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index b7189d1..7b52dae 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -30,6 +30,7 @@
<attr name="workspaceAmbientShadowColor" format="color"/>
<attr name="workspaceKeyShadowColor" format="color" />
<attr name="workspaceStatusBarScrim" format="reference" />
+ <attr name="widgetsTheme" format="reference" />
<!-- BubbleTextView specific attributes. -->
<declare-styleable name="BubbleTextView">
@@ -43,10 +44,15 @@
<enum name="shortcut_popup" value="4" />
</attr>
<attr name="deferShadowGeneration" format="boolean" />
- <attr name="customShadows" format="boolean" />
<attr name="centerVertically" format="boolean" />
+ </declare-styleable>
+
+ <declare-styleable name="ShadowInfo">
<attr name="ambientShadowColor" format="color" />
+ <attr name="ambientShadowBlur" format="dimension" />
<attr name="keyShadowColor" format="color" />
+ <attr name="keyShadowBlur" format="dimension" />
+ <attr name="keyShadowOffset" format="dimension" />
</declare-styleable>
<!-- PagedView specific attributes. These attributes are used to customize
@@ -111,9 +117,9 @@
<attr name="numHotseatIcons" format="integer" />
<attr name="iconSize" format="float" />
+ <!-- landscapeIconSize defaults to iconSize, if not specified -->
+ <attr name="landscapeIconSize" format="float" />
<attr name="iconTextSize" format="float" />
- <!-- hotseatIconSize defaults to iconSize, if not specified -->
- <attr name="hotseatIconSize" format="float" />
<attr name="defaultLayoutId" format="reference" />
</declare-styleable>
@@ -130,6 +136,10 @@
<attr name="android:src" />
<attr name="android:shadowColor" />
<attr name="android:elevation" />
- <attr name="android:tint" />
+ <attr name="darkTintColor" format="color"/>
+ </declare-styleable>
+
+ <declare-styleable name="RecyclerViewFastScroller">
+ <attr name="canThumbDetach" format="boolean" />
</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 3a531b0..a4dff71 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -16,26 +16,31 @@
<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_size">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>
+ <dimen name="dynamic_grid_page_indicator_gutter_width">50dp</dimen>
<dimen name="dynamic_grid_icon_drawable_padding">8dp</dimen>
<dimen name="dynamic_grid_overview_min_icon_zone_height">80dp</dimen>
<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>
+ <dimen name="dynamic_grid_hotseat_land_left_nav_bar_right_padding">0dp</dimen>
+ <dimen name="dynamic_grid_hotseat_land_right_nav_bar_right_padding">0dp</dimen>
+ <dimen name="dynamic_grid_hotseat_land_left_nav_bar_gutter_width">0dp</dimen>
+ <dimen name="dynamic_grid_hotseat_land_right_nav_bar_gutter_width">0dp</dimen>
<!-- Drop target bar -->
<dimen name="dynamic_grid_drop_target_size">48dp</dimen>
@@ -47,16 +52,28 @@
<dimen name="widget_handle_margin">13dp</dimen>
<dimen name="resize_frame_background_padding">24dp</dimen>
-<!-- Container -->
- <dimen name="container_fastscroll_thumb_min_width">5dp</dimen>
- <dimen name="container_fastscroll_thumb_max_width">9dp</dimen>
- <dimen name="container_fastscroll_popup_margin">18dp</dimen>
- <dimen name="container_fastscroll_thumb_height">72dp</dimen>
- <dimen name="container_fastscroll_thumb_touch_inset">-24dp</dimen>
- <dimen name="container_fastscroll_popup_size">72dp</dimen>
- <dimen name="container_fastscroll_popup_text_size">48dp</dimen>
+<!-- Fast scroll -->
+ <dimen name="fastscroll_track_min_width">6dp</dimen>
+ <dimen name="fastscroll_track_max_width">8dp</dimen>
+ <dimen name="fastscroll_thumb_padding">1dp</dimen>
+ <dimen name="fastscroll_thumb_height">52dp</dimen>
+ <dimen name="fastscroll_thumb_touch_inset">-24dp</dimen>
-<!-- All Apps -->
+ <dimen name="fastscroll_popup_width">75dp</dimen>
+ <dimen name="fastscroll_popup_height">62dp</dimen>
+ <dimen name="fastscroll_popup_padding">13dp</dimen>
+ <dimen name="fastscroll_popup_text_size">32dp</dimen>
+ <dimen name="fastscroll_popup_margin">19dp</dimen>
+
+ <!--
+ Fast scroller draws the content horizontally centered. The end of the track should be
+ aligned at the end of the container.
+ fastscroll_end_margin = - (fastscroll_width - fastscroll_track_min_width) / 2
+ -->
+ <dimen name="fastscroll_width">58dp</dimen>
+ <dimen name="fastscroll_end_margin">-26dp</dimen>
+
+ <!-- All Apps -->
<dimen name="all_apps_button_scale_down">0dp</dimen>
<dimen name="all_apps_search_bar_field_height">48dp</dimen>
<dimen name="all_apps_search_bar_height">60dp</dimen>
@@ -67,7 +84,7 @@
<dimen name="all_apps_caret_stroke_width">2dp</dimen>
<dimen name="all_apps_caret_shadow_spread">1dp</dimen>
<dimen name="all_apps_caret_size">13dp</dimen>
- <dimen name="all_apps_caret_workspace_offset">4dp</dimen>
+ <dimen name="all_apps_caret_workspace_offset">18dp</dimen>
<!-- Search bar in All Apps -->
<dimen name="all_apps_header_max_elevation">3dp</dimen>
@@ -148,6 +165,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>
@@ -191,7 +209,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 8af6968..d11b002 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -40,6 +40,7 @@
<item name="workspaceAmbientShadowColor">#33000000</item>
<item name="workspaceKeyShadowColor">#44000000</item>
<item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
+ <item name="widgetsTheme">@style/WidgetContainerTheme</item>
</style>
<style name="LauncherTheme" parent="@style/BaseLauncherThemeWithCustomAttrs"></style>
@@ -64,6 +65,7 @@
<item name="popupColorPrimary">?android:attr/colorPrimary</item>
<item name="popupColorSecondary">#424242</item> <!-- Gray 800 -->
<item name="popupColorTertiary">#757575</item> <!-- Gray 600 -->
+ <item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
<item name="isMainColorDark">true</item>
</style>
@@ -85,12 +87,14 @@
<item name="android:textColorSecondary">?android:attr/textColorSecondaryInverse</item>
</style>
+ <style name="WidgetContainerTheme.Dark" />
+
<style name="FastScrollerPopup" >
- <item name="android:background">@drawable/container_fastscroll_popup_bg</item>
<item name="android:layout_width">wrap_content</item>
- <item name="android:minWidth">@dimen/container_fastscroll_popup_size</item>
- <item name="android:layout_height">@dimen/container_fastscroll_popup_size</item>
- <item name="android:textSize">@dimen/container_fastscroll_popup_text_size</item>
+ <item name="android:minWidth">@dimen/fastscroll_popup_width</item>
+ <item name="android:layout_height">@dimen/fastscroll_popup_height</item>
+ <item name="android:textSize">@dimen/fastscroll_popup_text_size</item>
+ <item name="android:paddingEnd">@dimen/fastscroll_popup_padding</item>
<item name="android:gravity">center</item>
<item name="android:alpha">0</item>
<item name="android:elevation">3dp</item>
@@ -119,16 +123,17 @@
<!-- No shadows in the base theme -->
<item name="android:shadowRadius">0</item>
- <item name="customShadows">false</item>
</style>
<!-- Icon displayed on the worksapce -->
<style name="BaseIcon.Workspace">
- <item name="customShadows">true</item>
<item name="android:shadowRadius">2.0</item>
<item name="android:shadowColor">?attr/workspaceShadowColor</item>
- <item name="keyShadowColor">?attr/workspaceKeyShadowColor</item>
<item name="ambientShadowColor">?attr/workspaceAmbientShadowColor</item>
+ <item name="ambientShadowBlur">2.5dp</item>
+ <item name="keyShadowColor">?attr/workspaceKeyShadowColor</item>
+ <item name="keyShadowBlur">1dp</item>
+ <item name="keyShadowOffset">.5dp</item>
</style>
<!-- Theme for the popup container -->
@@ -156,4 +161,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/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index aeda1a2..c582fc5 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -29,7 +29,6 @@
launcher:iconSize="48"
launcher:iconTextSize="13.0"
launcher:numHotseatIcons="3"
- launcher:hotseatIconSize="48"
launcher:defaultLayoutId="@xml/default_workspace_3x3"
/>
@@ -45,7 +44,6 @@
launcher:iconSize="48"
launcher:iconTextSize="13.0"
launcher:numHotseatIcons="3"
- launcher:hotseatIconSize="48"
launcher:defaultLayoutId="@xml/default_workspace_3x3"
/>
@@ -61,7 +59,6 @@
launcher:iconSize="48"
launcher:iconTextSize="13.0"
launcher:numHotseatIcons="5"
- launcher:hotseatIconSize="48"
launcher:defaultLayoutId="@xml/default_workspace_4x4"
/>
@@ -77,7 +74,6 @@
launcher:iconSize="48"
launcher:iconTextSize="13.0"
launcher:numHotseatIcons="5"
- launcher:hotseatIconSize="48"
launcher:defaultLayoutId="@xml/default_workspace_4x4"
/>
@@ -93,7 +89,6 @@
launcher:iconSize="48"
launcher:iconTextSize="13.0"
launcher:numHotseatIcons="5"
- launcher:hotseatIconSize="48"
launcher:defaultLayoutId="@xml/default_workspace_4x4"
/>
@@ -106,10 +101,9 @@
launcher:numFolderRows="4"
launcher:numFolderColumns="4"
launcher:minAllAppsPredictionColumns="4"
- launcher:iconSize="60"
+ launcher:iconSize="54"
launcher:iconTextSize="13.0"
launcher:numHotseatIcons="5"
- launcher:hotseatIconSize="56"
launcher:defaultLayoutId="@xml/default_workspace_4x4"
/>
@@ -122,10 +116,9 @@
launcher:numFolderRows="4"
launcher:numFolderColumns="4"
launcher:minAllAppsPredictionColumns="4"
- launcher:iconSize="60"
+ launcher:iconSize="54"
launcher:iconTextSize="13.0"
launcher:numHotseatIcons="5"
- launcher:hotseatIconSize="56"
launcher:defaultLayoutId="@xml/default_workspace_4x4"
/>
@@ -138,10 +131,9 @@
launcher:numFolderRows="4"
launcher:numFolderColumns="4"
launcher:minAllAppsPredictionColumns="4"
- launcher:iconSize="64"
+ launcher:iconSize="56"
launcher:iconTextSize="14.4"
launcher:numHotseatIcons="5"
- launcher:hotseatIconSize="56"
launcher:defaultLayoutId="@xml/default_workspace_5x5"
/>
@@ -154,10 +146,9 @@
launcher:numFolderRows="4"
launcher:numFolderColumns="5"
launcher:minAllAppsPredictionColumns="4"
- launcher:iconSize="72"
+ launcher:iconSize="64"
launcher:iconTextSize="14.4"
launcher:numHotseatIcons="7"
- launcher:hotseatIconSize="60"
launcher:defaultLayoutId="@xml/default_workspace_5x6"
/>
@@ -173,7 +164,6 @@
launcher:iconSize="76"
launcher:iconTextSize="14.4"
launcher:numHotseatIcons="7"
- launcher:hotseatIconSize="76"
launcher:defaultLayoutId="@xml/default_workspace_5x6"
/>
@@ -189,7 +179,6 @@
launcher:iconSize="100"
launcher:iconTextSize="20.0"
launcher:numHotseatIcons="7"
- launcher:hotseatIconSize="72"
launcher:defaultLayoutId="@xml/default_workspace_5x6"
/>
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 939fece..c76f118 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -16,23 +16,6 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <SwitchPreference
- android:key="pref_add_icon_to_home"
- android:title="@string/auto_add_shortcuts_label"
- android:summary="@string/auto_add_shortcuts_description"
- android:defaultValue="true"
- android:persistent="true"
- />
-
- <ListPreference
- android:key="pref_override_icon_shape"
- android:title="@string/icon_shape_override_label"
- android:summary="%s"
- android:entries="@array/icon_shape_override_paths_names"
- android:entryValues="@array/icon_shape_override_paths_values"
- android:defaultValue=""
- android:persistent="false" />
-
<Preference
android:key="pref_icon_badging"
android:title="@string/icon_badging_title"
@@ -46,10 +29,27 @@
</Preference>
<SwitchPreference
+ android:key="pref_add_icon_to_home"
+ android:title="@string/auto_add_shortcuts_label"
+ android:summary="@string/auto_add_shortcuts_description"
+ android:defaultValue="true"
+ android:persistent="true"
+ />
+
+ <SwitchPreference
android:key="pref_allowRotation"
android:title="@string/allow_rotation_title"
android:defaultValue="@bool/allow_rotation"
android:persistent="true"
/>
+ <ListPreference
+ android:key="pref_override_icon_shape"
+ android:title="@string/icon_shape_override_label"
+ android:summary="%s"
+ android:entries="@array/icon_shape_override_paths_names"
+ android:entryValues="@array/icon_shape_override_paths_values"
+ android:defaultValue=""
+ android:persistent="false" />
+
</PreferenceScreen>
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 08cd955..2b59ede 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -22,11 +22,13 @@
import android.view.View.AccessibilityDelegate;
import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.util.SystemUiController;
public abstract class BaseActivity extends Activity {
protected DeviceProfile mDeviceProfile;
protected UserEventDispatcher mUserEventDispatcher;
+ protected SystemUiController mSystemUiController;
public DeviceProfile getDeviceProfile() {
return mDeviceProfile;
@@ -54,4 +56,11 @@
}
return ((BaseActivity) ((ContextWrapper) context).getBaseContext());
}
+
+ public SystemUiController getSystemUiController() {
+ if (mSystemUiController == null) {
+ mSystemUiController = new SystemUiController(getWindow());
+ }
+ return mSystemUiController;
+ }
}
diff --git a/src/com/android/launcher3/BaseContainerView.java b/src/com/android/launcher3/BaseContainerView.java
index ac7cbaf..c55a586 100644
--- a/src/com/android/launcher3/BaseContainerView.java
+++ b/src/com/android/launcher3/BaseContainerView.java
@@ -113,20 +113,18 @@
* Calculate the background padding as it can change due to insets/content padding change.
*/
private void updatePaddings() {
- Context context = getContext();
- int paddingLeft;
- int paddingRight;
- int paddingTop;
- int paddingBottom;
-
- DeviceProfile grid = Launcher.getLauncher(context).getDeviceProfile();
+ DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
int[] padding = grid.getContainerPadding();
- paddingLeft = padding[0] + grid.edgeMarginPx;
- paddingRight = padding[1] + grid.edgeMarginPx;
+
+ int paddingLeft = padding[0];
+ int paddingRight = padding[1];
+ int paddingTop = 0;
+ int paddingBottom = 0;
+
if (!grid.isVerticalBarLayout()) {
+ paddingLeft += grid.edgeMarginPx;
+ paddingRight += grid.edgeMarginPx;
paddingTop = paddingBottom = grid.edgeMarginPx;
- } else {
- paddingTop = paddingBottom = 0;
}
updateBackground(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 514cc07..3ee6e51 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -22,8 +22,9 @@
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
+import android.widget.TextView;
-import com.android.launcher3.util.Thunk;
+import com.android.launcher3.views.RecyclerViewFastScroller;
/**
@@ -36,19 +37,7 @@
public abstract class BaseRecyclerView extends RecyclerView
implements RecyclerView.OnItemTouchListener {
- private static final int SCROLL_DELTA_THRESHOLD_DP = 4;
-
- /** Keeps the last known scrolling delta/velocity along y-axis. */
- @Thunk int mDy = 0;
- private float mDeltaThreshold;
-
- protected final BaseRecyclerViewFastScrollBar mScrollbar;
-
- private int mDownX;
- private int mDownY;
- private int mLastY;
-
- private boolean mScrollBarVisible = true;
+ protected RecyclerViewFastScroller mScrollbar;
public BaseRecyclerView(Context context) {
this(context, null);
@@ -60,28 +49,6 @@
public BaseRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- mDeltaThreshold = getResources().getDisplayMetrics().density * SCROLL_DELTA_THRESHOLD_DP;
- mScrollbar = new BaseRecyclerViewFastScrollBar(this, getResources());
-
- ScrollListener listener = new ScrollListener();
- setOnScrollListener(listener);
- }
-
- private class ScrollListener extends OnScrollListener {
- public ScrollListener() {
- // Do nothing
- }
-
- @Override
- public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
- mDy = dy;
-
- // TODO(winsonc): If we want to animate the section heads while scrolling, we can
- // initiate that here if the recycler view scroll state is not
- // RecyclerView.SCROLL_STATE_IDLE.
-
- onUpdateScrollbar(dy);
- }
}
@Override
@@ -93,7 +60,9 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- mScrollbar.setPopupView(((ViewGroup) getParent()).findViewById(R.id.fast_scroller_popup));
+ ViewGroup parent = (ViewGroup) getParent();
+ mScrollbar = parent.findViewById(R.id.fast_scroller);
+ mScrollbar.setRecyclerView(this, (TextView) parent.findViewById(R.id.fast_scroller_popup));
}
/**
@@ -115,32 +84,15 @@
* it is already showing).
*/
private boolean handleTouchEvent(MotionEvent ev) {
- ev.offsetLocation(0, -getPaddingTop());
- int action = ev.getAction();
- int x = (int) ev.getX();
- int y = (int) ev.getY();
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- // Keep track of the down positions
- mDownX = x;
- mDownY = mLastY = y;
- if (shouldStopScroll(ev)) {
- stopScroll();
- }
- mScrollbar.handleTouchEvent(ev, mDownX, mDownY, mLastY);
- break;
- case MotionEvent.ACTION_MOVE:
- mLastY = y;
- mScrollbar.handleTouchEvent(ev, mDownX, mDownY, mLastY);
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- onFastScrollCompleted();
- mScrollbar.handleTouchEvent(ev, mDownX, mDownY, mLastY);
- break;
+ // Move to mScrollbar's coordinate system.
+ int left = getLeft() - mScrollbar.getLeft();
+ int top = getTop() - mScrollbar.getTop();
+ ev.offsetLocation(left, top);
+ try {
+ return mScrollbar.handleTouchEvent(ev);
+ } finally {
+ ev.offsetLocation(-left, -top);
}
- ev.offsetLocation(0, getPaddingTop());
- return mScrollbar.isDraggingThumb();
}
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
@@ -148,24 +100,9 @@
}
/**
- * Returns whether this {@link MotionEvent} should trigger the scroll to be stopped.
- */
- protected boolean shouldStopScroll(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- if ((Math.abs(mDy) < mDeltaThreshold &&
- getScrollState() != RecyclerView.SCROLL_STATE_IDLE)) {
- // now the touch events are being passed to the {@link WidgetCell} until the
- // touch sequence goes over the touch slop.
- return true;
- }
- }
- return false;
- }
-
- /**
* Returns the height of the fast scroll bar
*/
- protected int getScrollbarTrackHeight() {
+ public int getScrollbarTrackHeight() {
return getHeight() - getPaddingTop() - getPaddingBottom();
}
@@ -185,34 +122,16 @@
}
/**
- * Returns the track color (ignoring alpha), can be overridden by each subclass.
- */
- public int getFastScrollerTrackColor(int defaultTrackColor) {
- return defaultTrackColor;
- }
-
- /**
* Returns the scrollbar for this recycler view.
*/
- public BaseRecyclerViewFastScrollBar getScrollBar() {
+ public RecyclerViewFastScroller getScrollBar() {
return mScrollbar;
}
@Override
protected void dispatchDraw(Canvas canvas) {
+ onUpdateScrollbar(0);
super.dispatchDraw(canvas);
- if (mScrollBarVisible) {
- onUpdateScrollbar(0);
- mScrollbar.draw(canvas);
- }
- }
-
- /**
- * Sets the scrollbar visibility. The call does not refresh the UI, its the responsibility
- * of the caller to call {@link #invalidate()}.
- */
- public void setScrollBarVisible(boolean visible) {
- mScrollBarVisible = visible;
}
/**
@@ -243,7 +162,7 @@
/**
* @return whether fast scrolling is supported in the current state.
*/
- protected boolean supportsFastScrolling() {
+ public boolean supportsFastScrolling() {
return true;
}
@@ -259,16 +178,16 @@
* Maps the touch (from 0..1) to the adapter position that should be visible.
* <p>Override in each subclass of this base class.
*/
- protected abstract String scrollToPositionAtProgress(float touchFraction);
+ public abstract String scrollToPositionAtProgress(float touchFraction);
/**
* Updates the bounds for the scrollbar.
* <p>Override in each subclass of this base class.
*/
- protected abstract void onUpdateScrollbar(int dy);
+ public abstract void onUpdateScrollbar(int dy);
/**
* <p>Override in each subclass of this base class.
*/
- protected void onFastScrollCompleted() {}
+ public void onFastScrollCompleted() {}
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
deleted file mode 100644
index 3039744..0000000
--- a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-package com.android.launcher3;
-
-import android.animation.ObjectAnimator;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Rect;
-import android.util.Property;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.widget.TextView;
-
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.Themes;
-
-/**
- * The track and scrollbar that shows when you scroll the list.
- */
-public class BaseRecyclerViewFastScrollBar {
-
- private static final Property<BaseRecyclerViewFastScrollBar, Integer> TRACK_WIDTH =
- new Property<BaseRecyclerViewFastScrollBar, Integer>(Integer.class, "width") {
-
- @Override
- public Integer get(BaseRecyclerViewFastScrollBar scrollBar) {
- return scrollBar.mWidth;
- }
-
- @Override
- public void set(BaseRecyclerViewFastScrollBar scrollBar, Integer value) {
- scrollBar.setTrackWidth(value);
- }
- };
-
- private final static int MAX_TRACK_ALPHA = 30;
- private final static int SCROLL_BAR_VIS_DURATION = 150;
- private static final float FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR = 1.5f;
-
- private final Rect mTmpRect = new Rect();
- private final BaseRecyclerView mRv;
-
- private final boolean mIsRtl;
-
- // The inset is the buffer around which a point will still register as a click on the scrollbar
- private final int mTouchInset;
-
- private final int mMinWidth;
- private final int mMaxWidth;
-
- // Current width of the track
- private int mWidth;
- private ObjectAnimator mWidthAnimator;
-
- private final Path mThumbPath = new Path();
- private final Paint mThumbPaint;
- private final int mThumbHeight;
-
- private final Paint mTrackPaint;
-
- private float mLastTouchY;
- private boolean mIsDragging;
- private boolean mIsThumbDetached;
- private boolean mCanThumbDetach;
- private boolean mIgnoreDragGesture;
-
- // This is the offset from the top of the scrollbar when the user first starts touching. To
- // prevent jumping, this offset is applied as the user scrolls.
- private int mTouchOffsetY;
- private int mThumbOffsetY;
-
- // Fast scroller popup
- private TextView mPopupView;
- private boolean mPopupVisible;
- private String mPopupSectionName;
-
- public BaseRecyclerViewFastScrollBar(BaseRecyclerView rv, Resources res) {
- mRv = rv;
- mTrackPaint = new Paint();
- mTrackPaint.setColor(rv.getFastScrollerTrackColor(Color.BLACK));
- mTrackPaint.setAlpha(MAX_TRACK_ALPHA);
-
- mThumbPaint = new Paint();
- mThumbPaint.setAntiAlias(true);
- mThumbPaint.setColor(Themes.getColorAccent(rv.getContext()));
- mThumbPaint.setStyle(Paint.Style.FILL);
-
- mWidth = mMinWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_min_width);
- mMaxWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_max_width);
- mThumbHeight = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_height);
- mTouchInset = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_touch_inset);
- mIsRtl = Utilities.isRtl(res);
- updateThumbPath();
- }
-
- public void setPopupView(View popup) {
- mPopupView = (TextView) popup;
- }
-
- public void setDetachThumbOnFastScroll() {
- mCanThumbDetach = true;
- }
-
- public void reattachThumbToScroll() {
- mIsThumbDetached = false;
- }
-
- private int getDrawLeft() {
- return mIsRtl ? 0 : (mRv.getWidth() - mMaxWidth);
- }
-
- public void setThumbOffsetY(int y) {
- if (mThumbOffsetY == y) {
- return;
- }
-
- // Invalidate the previous and new thumb area
- int drawLeft = getDrawLeft();
- mTmpRect.set(drawLeft, mThumbOffsetY, drawLeft + mMaxWidth, mThumbOffsetY + mThumbHeight);
- mThumbOffsetY = y;
- mTmpRect.union(drawLeft, mThumbOffsetY, drawLeft + mMaxWidth, mThumbOffsetY + mThumbHeight);
- mTmpRect.offset(0, mRv.getPaddingTop());
- mRv.invalidate(mTmpRect);
- }
-
- public int getThumbOffsetY() {
- return mThumbOffsetY;
- }
-
- private void setTrackWidth(int width) {
- if (mWidth == width) {
- return;
- }
- int left = getDrawLeft();
- int top = mRv.getPaddingTop();
- // Invalidate the whole scroll bar area.
- mRv.invalidate(left, top, left + mMaxWidth, top + mRv.getScrollbarTrackHeight());
-
- mWidth = width;
- updateThumbPath();
- }
-
- /**
- * Updates the path for the thumb drawable.
- */
- private void updateThumbPath() {
- int smallWidth = mIsRtl ? mWidth : -mWidth;
- int largeWidth = mIsRtl ? mMaxWidth : -mMaxWidth;
-
- mThumbPath.reset();
- mThumbPath.moveTo(0, 0);
- mThumbPath.lineTo(0, mThumbHeight); // Left edge
- mThumbPath.lineTo(smallWidth, mThumbHeight); // bottom edge
- mThumbPath.cubicTo(smallWidth, mThumbHeight, // right edge
- largeWidth, mThumbHeight / 2,
- smallWidth, 0);
- mThumbPath.close();
- }
-
- public int getThumbHeight() {
- return mThumbHeight;
- }
-
- public boolean isDraggingThumb() {
- return mIsDragging;
- }
-
- public boolean isThumbDetached() {
- return mIsThumbDetached;
- }
-
- /**
- * Handles the touch event and determines whether to show the fast scroller (or updates it if
- * it is already showing).
- */
- public void handleTouchEvent(MotionEvent ev, int downX, int downY, int lastY) {
- ViewConfiguration config = ViewConfiguration.get(mRv.getContext());
-
- int action = ev.getAction();
- int y = (int) ev.getY();
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- if (isNearThumb(downX, downY)) {
- mTouchOffsetY = downY - mThumbOffsetY;
- } else if (FeatureFlags.LAUNCHER3_DIRECT_SCROLL
- && mRv.supportsFastScrolling()
- && isNearScrollBar(downX)) {
- calcTouchOffsetAndPrepToFastScroll(downY, lastY);
- updateFastScrollSectionNameAndThumbOffset(lastY, y);
- }
- break;
- case MotionEvent.ACTION_MOVE:
- // Check if we should start scrolling, but ignore this fastscroll gesture if we have
- // exceeded some fixed movement
- mIgnoreDragGesture |= Math.abs(y - downY) > config.getScaledPagingTouchSlop();
- if (!mIsDragging && !mIgnoreDragGesture && mRv.supportsFastScrolling() &&
- isNearThumb(downX, lastY) &&
- Math.abs(y - downY) > config.getScaledTouchSlop()) {
- calcTouchOffsetAndPrepToFastScroll(downY, lastY);
- }
- if (mIsDragging) {
- updateFastScrollSectionNameAndThumbOffset(lastY, y);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- mTouchOffsetY = 0;
- mLastTouchY = 0;
- mIgnoreDragGesture = false;
- if (mIsDragging) {
- mIsDragging = false;
- animatePopupVisibility(false);
- showActiveScrollbar(false);
- }
- break;
- }
- }
-
- private void calcTouchOffsetAndPrepToFastScroll(int downY, int lastY) {
- mRv.getParent().requestDisallowInterceptTouchEvent(true);
- mIsDragging = true;
- if (mCanThumbDetach) {
- mIsThumbDetached = true;
- }
- mTouchOffsetY += (lastY - downY);
- animatePopupVisibility(true);
- showActiveScrollbar(true);
- }
-
- private void updateFastScrollSectionNameAndThumbOffset(int lastY, int y) {
- // Update the fastscroller section name at this touch position
- int bottom = mRv.getScrollbarTrackHeight() - mThumbHeight;
- float boundedY = (float) Math.max(0, Math.min(bottom, y - mTouchOffsetY));
- String sectionName = mRv.scrollToPositionAtProgress(boundedY / bottom);
- if (!sectionName.equals(mPopupSectionName)) {
- mPopupSectionName = sectionName;
- mPopupView.setText(sectionName);
- }
- animatePopupVisibility(!sectionName.isEmpty());
- updatePopupY(lastY);
- mLastTouchY = boundedY;
- setThumbOffsetY((int) mLastTouchY);
- }
-
- public void draw(Canvas canvas) {
- if (mThumbOffsetY < 0) {
- return;
- }
- int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
- if (!mIsRtl) {
- canvas.translate(mRv.getWidth(), 0);
- }
- canvas.translate(0, mRv.getPaddingTop());
- // Draw the track
- int thumbWidth = mIsRtl ? mWidth : -mWidth;
- canvas.drawRect(0, 0, thumbWidth, mRv.getScrollbarTrackHeight(), mTrackPaint);
-
- canvas.translate(0, mThumbOffsetY);
- canvas.drawPath(mThumbPath, mThumbPaint);
- canvas.restoreToCount(saveCount);
- }
-
- /**
- * Animates the width of the scrollbar.
- */
- private void showActiveScrollbar(boolean isScrolling) {
- if (mWidthAnimator != null) {
- mWidthAnimator.cancel();
- }
-
- mWidthAnimator = ObjectAnimator.ofInt(this, TRACK_WIDTH,
- isScrolling ? mMaxWidth : mMinWidth);
- mWidthAnimator.setDuration(SCROLL_BAR_VIS_DURATION);
- mWidthAnimator.start();
- }
-
- /**
- * Returns whether the specified point is inside the thumb bounds.
- */
- public boolean isNearThumb(int x, int y) {
- int left = getDrawLeft();
- mTmpRect.set(left, mThumbOffsetY, left + mMaxWidth, mThumbOffsetY + mThumbHeight);
- mTmpRect.inset(mTouchInset, mTouchInset);
- return mTmpRect.contains(x, y);
- }
-
- /**
- * Returns whether the specified x position is near the scroll bar.
- */
- public boolean isNearScrollBar(int x) {
- int left = getDrawLeft();
- return x >= left && x <= left + mMaxWidth;
- }
-
- private void animatePopupVisibility(boolean visible) {
- if (mPopupVisible != visible) {
- mPopupVisible = visible;
- mPopupView.animate().cancel();
- mPopupView.animate().alpha(visible ? 1f : 0f).setDuration(visible ? 200 : 150).start();
- }
- }
-
- private void updatePopupY(int lastTouchY) {
- int height = mPopupView.getHeight();
- float top = lastTouchY - (FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR * height);
- top = Math.max(mMaxWidth, Math.min(top, mRv.getScrollbarTrackHeight() - mMaxWidth - height));
- mPopupView.setTranslationY(top);
- }
-}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 27e190e..6f2c897 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -19,7 +19,6 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -27,9 +26,9 @@
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.util.Property;
import android.util.TypedValue;
@@ -61,11 +60,6 @@
*/
public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
- // Dimensions in DP
- private static final float AMBIENT_SHADOW_RADIUS = 2.5f;
- private static final float KEY_SHADOW_RADIUS = 1f;
- private static final float KEY_SHADOW_OFFSET = 0.5f;
-
private static final int DISPLAY_WORKSPACE = 0;
private static final int DISPLAY_ALL_APPS = 1;
private static final int DISPLAY_FOLDER = 2;
@@ -75,22 +69,15 @@
private final Launcher mLauncher;
private Drawable mIcon;
private final boolean mCenterVertically;
- private final Drawable mBackground;
- private OnLongClickListener mOnLongClickListener;
+
private final CheckLongPressHelper mLongPressHelper;
private final HolographicOutlineHelper mOutlineHelper;
private final StylusEventHelper mStylusEventHelper;
- private final int mAmbientShadowColor;
- private final int mKeyShadowColor;
-
- private boolean mBackgroundSizeChanged;
+ private final float mSlop;
private Bitmap mPressedBackground;
- private float mSlop;
-
private final boolean mDeferShadowGenerationOnTouch;
- private final boolean mCustomShadowsEnabled;
private final boolean mLayoutHorizontal;
private final int mIconSize;
@ViewDebug.ExportedProperty(category = "launcher")
@@ -119,6 +106,19 @@
}
};
+ public static final Property<BubbleTextView, Integer> TEXT_ALPHA_PROPERTY
+ = new Property<BubbleTextView, Integer>(Integer.class, "textAlpha") {
+ @Override
+ public Integer get(BubbleTextView bubbleTextView) {
+ return bubbleTextView.getTextAlpha();
+ }
+
+ @Override
+ public void set(BubbleTextView bubbleTextView, Integer alpha) {
+ bubbleTextView.setTextAlpha(alpha);
+ }
+ };
+
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mStayPressed;
@ViewDebug.ExportedProperty(category = "launcher")
@@ -140,20 +140,19 @@
super(context, attrs, defStyle);
mLauncher = Launcher.getLauncher(context);
DeviceProfile grid = mLauncher.getDeviceProfile();
+ mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.BubbleTextView, defStyle, 0);
- mCustomShadowsEnabled = a.getBoolean(R.styleable.BubbleTextView_customShadows, false);
mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false);
mDeferShadowGenerationOnTouch =
a.getBoolean(R.styleable.BubbleTextView_deferShadowGeneration, false);
- mAmbientShadowColor = a.getColor(R.styleable.BubbleTextView_ambientShadowColor, 0x33000000);
- mKeyShadowColor = a.getColor(R.styleable.BubbleTextView_keyShadowColor, 0x66000000);
int display = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE);
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);
@@ -169,23 +168,12 @@
defaultIconSize);
a.recycle();
- if (mCustomShadowsEnabled) {
- // Draw the background itself as the parent is drawn twice.
- mBackground = getBackground();
- setBackground(null);
-
- // Set shadow layer as the larger shadow to that the textView does not clip the shadow.
- float density = getResources().getDisplayMetrics().density;
- setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, mAmbientShadowColor);
- } else {
- mBackground = null;
- }
-
mLongPressHelper = new CheckLongPressHelper(this);
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
mOutlineHelper = HolographicOutlineHelper.getInstance(getContext());
setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
+
}
public void applyFromShortcutInfo(ShortcutInfo info) {
@@ -247,19 +235,6 @@
}
@Override
- protected boolean setFrame(int left, int top, int right, int bottom) {
- if (getLeft() != left || getRight() != right || getTop() != top || getBottom() != bottom) {
- mBackgroundSizeChanged = true;
- }
- return super.setFrame(left, top, right, bottom);
- }
-
- @Override
- protected boolean verifyDrawable(Drawable who) {
- return who == mBackground || super.verifyDrawable(who);
- }
-
- @Override
public void setTag(Object tag) {
if (tag != null) {
LauncherModel.checkItemInfo((ItemInfo) tag);
@@ -288,21 +263,6 @@
return mIcon;
}
- /** Returns whether the layout is horizontal. */
- public boolean isLayoutHorizontal() {
- return mLayoutHorizontal;
- }
-
- @Override
- public void setOnLongClickListener(OnLongClickListener l) {
- super.setOnLongClickListener(l);
- mOnLongClickListener = l;
- }
-
- public OnLongClickListener getOnLongClickListener() {
- return mOnLongClickListener;
- }
-
@Override
public boolean onTouchEvent(MotionEvent event) {
// Call the superclass onTouchEvent first, because sometimes it changes the state to
@@ -400,54 +360,14 @@
return result;
}
+ @SuppressWarnings("wrongcall")
+ protected void drawWithoutBadge(Canvas canvas) {
+ super.onDraw(canvas);
+ }
+
@Override
- public void draw(Canvas canvas) {
- if (!mCustomShadowsEnabled) {
- super.draw(canvas);
- drawBadgeIfNecessary(canvas);
- return;
- }
-
- final Drawable background = mBackground;
- if (background != null) {
- final int scrollX = getScrollX();
- final int scrollY = getScrollY();
-
- if (mBackgroundSizeChanged) {
- background.setBounds(0, 0, getRight() - getLeft(), getBottom() - getTop());
- mBackgroundSizeChanged = false;
- }
-
- if ((scrollX | scrollY) == 0) {
- background.draw(canvas);
- } else {
- canvas.translate(scrollX, scrollY);
- background.draw(canvas);
- canvas.translate(-scrollX, -scrollY);
- }
- }
-
- // If text is transparent, don't draw any shadow
- if ((getCurrentTextColor() >> 24) == 0) {
- getPaint().clearShadowLayer();
- super.draw(canvas);
- drawBadgeIfNecessary(canvas);
- return;
- }
-
- // We enhance the shadow by drawing the shadow twice
- float density = getResources().getDisplayMetrics().density;
- getPaint().setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, mAmbientShadowColor);
- super.draw(canvas);
- canvas.save(Canvas.CLIP_SAVE_FLAG);
- canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
- getScrollX() + getWidth(),
- getScrollY() + getHeight(), Region.Op.INTERSECT);
- getPaint().setShadowLayer(
- density * KEY_SHADOW_RADIUS, 0.0f, density * KEY_SHADOW_OFFSET, mKeyShadowColor);
- super.draw(canvas);
- canvas.restore();
-
+ public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
drawBadgeIfNecessary(canvas);
}
@@ -455,7 +375,7 @@
* Draws the icon badge in the top right corner of the icon bounds.
* @param canvas The canvas to draw to.
*/
- private void drawBadgeIfNecessary(Canvas canvas) {
+ protected void drawBadgeIfNecessary(Canvas canvas) {
if (!mForceHideBadge && (hasBadge() || mBadgeScale > 0)) {
getIconBounds(mTempIconBounds);
mTempSpaceForBadgeOffset.set((getWidth() - mIconSize) / 2, getPaddingTop());
@@ -494,14 +414,6 @@
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- if (mBackground != null) mBackground.setCallback(this);
- mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mCenterVertically) {
Paint.FontMetrics fm = getPaint().getFontMetrics();
@@ -515,12 +427,6 @@
}
@Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (mBackground != null) mBackground.setCallback(null);
- }
-
- @Override
public void setTextColor(int color) {
mTextColor = color;
super.setTextColor(color);
@@ -533,14 +439,29 @@
}
public void setTextVisibility(boolean visible) {
- Resources res = getResources();
if (visible) {
super.setTextColor(mTextColor);
} else {
- super.setTextColor(res.getColor(android.R.color.transparent));
+ setTextAlpha(0);
}
}
+ private void setTextAlpha(int alpha) {
+ super.setTextColor(ColorUtils.setAlphaComponent(mTextColor, alpha));
+ }
+
+ private int getTextAlpha() {
+ return Color.alpha(getCurrentTextColor());
+ }
+
+ /**
+ * Creates an animator to fade the text in or out.
+ * @param fadeIn Whether the text should fade in or fade out.
+ */
+ public ObjectAnimator createTextAlphaAnimator(boolean fadeIn) {
+ return ObjectAnimator.ofInt(this, TEXT_ALPHA_PROPERTY, fadeIn ? Color.alpha(mTextColor) : 0);
+ }
+
@Override
public void cancelLongPress() {
super.cancelLongPress();
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/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index d0d33a0..d99a30a 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -53,6 +53,7 @@
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.util.CellAndSpan;
import com.android.launcher3.util.GridOccupancy;
@@ -102,8 +103,8 @@
private OnTouchListener mInterceptTouchListener;
private final StylusEventHelper mStylusEventHelper;
- private final ArrayList<FolderIcon.PreviewBackground> mFolderBackgrounds = new ArrayList<>();
- final FolderIcon.PreviewBackground mFolderLeaveBehind = new FolderIcon.PreviewBackground();
+ private final ArrayList<PreviewBackground> mFolderBackgrounds = new ArrayList<>();
+ final PreviewBackground mFolderLeaveBehind = new PreviewBackground();
private float mBackgroundAlpha;
@@ -153,7 +154,7 @@
@ContainerType private final int mContainerType;
- private final float mChildScale;
+ private final float mChildScale = 1f;
public static final int MODE_SHOW_REORDER_HINT = 0;
public static final int MODE_DRAG_OVER = 1;
@@ -217,8 +218,6 @@
mFolderLeaveBehind.delegateCellX = -1;
mFolderLeaveBehind.delegateCellY = -1;
- mChildScale = mContainerType == HOTSEAT ? grid.inv.hotseatScale : 1f;
-
setAlwaysDrawnWithCacheEnabled(false);
final Resources res = getResources();
@@ -495,7 +494,7 @@
}
for (int i = 0; i < mFolderBackgrounds.size(); i++) {
- FolderIcon.PreviewBackground bg = mFolderBackgrounds.get(i);
+ PreviewBackground bg = mFolderBackgrounds.get(i);
cellToPoint(bg.delegateCellX, bg.delegateCellY, mTempLocation);
canvas.save();
canvas.translate(mTempLocation[0], mTempLocation[1]);
@@ -521,7 +520,7 @@
super.dispatchDraw(canvas);
for (int i = 0; i < mFolderBackgrounds.size(); i++) {
- FolderIcon.PreviewBackground bg = mFolderBackgrounds.get(i);
+ PreviewBackground bg = mFolderBackgrounds.get(i);
if (bg.isClipping) {
cellToPoint(bg.delegateCellX, bg.delegateCellY, mTempLocation);
canvas.save();
@@ -532,10 +531,10 @@
}
}
- public void addFolderBackground(FolderIcon.PreviewBackground bg) {
+ public void addFolderBackground(PreviewBackground bg) {
mFolderBackgrounds.add(bg);
}
- public void removeFolderBackground(FolderIcon.PreviewBackground bg) {
+ public void removeFolderBackground(PreviewBackground bg) {
mFolderBackgrounds.remove(bg);
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 9bb56d6..dcfb268 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -19,6 +19,7 @@
import android.appwidget.AppWidgetHostView;
import android.content.ComponentName;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
@@ -32,7 +33,6 @@
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.badge.BadgeRenderer;
-import com.android.launcher3.config.FeatureFlags;
import java.util.ArrayList;
@@ -80,9 +80,8 @@
public final int workspaceSpringLoadedBottomSpace;
// Page indicator
- private final int pageIndicatorHeightPx;
- private final int pageIndicatorLandGutterLeftNavBarPx;
- private final int pageIndicatorLandGutterRightNavBarPx;
+ private final int pageIndicatorSizePx;
+ private final int pageIndicatorLandGutterPx;
private final int pageIndicatorLandWorkspaceOffsetPx;
// Workspace icons
@@ -93,6 +92,7 @@
public int cellWidthPx;
public int cellHeightPx;
+ public int workspaceCellPaddingXPx;
// Folder
public int folderBackgroundOffset;
@@ -109,15 +109,17 @@
public int folderChildDrawablePaddingPx;
// Hotseat
- public int hotseatCellWidthPx;
public int hotseatCellHeightPx;
- public int hotseatIconSizePx;
public int hotseatBarHeightPx;
public int hotseatBarTopPaddingPx;
+ public int hotseatBarLeftNavBarRightPaddingPx;
+ public int hotseatBarRightNavBarRightPaddingPx;
public int hotseatBarBottomPaddingPx;
- public int hotseatLandGutterPx;
+ public int hotseatLandLeftNavBarGutterPx;
+ public int hotseatLandRightNavBarGutterPx;
// All apps
+ public int allAppsCellHeightPx;
public int allAppsNumCols;
public int allAppsNumPredictiveCols;
public int allAppsButtonVisualSize;
@@ -159,19 +161,22 @@
transposeLayoutWithOrientation =
res.getBoolean(R.bool.hotseat_transpose_layout_with_orientation);
+ context = getContext(context, isVerticalBarLayout()
+ ? Configuration.ORIENTATION_LANDSCAPE
+ : Configuration.ORIENTATION_PORTRAIT);
+ res = context.getResources();
+
+
ComponentName cn = new ComponentName(context.getPackageName(),
this.getClass().getName());
defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null);
edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
desiredWorkspaceLeftRightMarginPx = edgeMarginPx;
- pageIndicatorHeightPx =
- res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_height);
- pageIndicatorLandGutterLeftNavBarPx = res.getDimensionPixelSize(
- R.dimen.dynamic_grid_page_indicator_gutter_width_left_nav_bar);
+ pageIndicatorSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_size);
+ pageIndicatorLandGutterPx = res.getDimensionPixelSize(
+ R.dimen.dynamic_grid_page_indicator_gutter_width);
pageIndicatorLandWorkspaceOffsetPx =
res.getDimensionPixelSize(R.dimen.all_apps_caret_workspace_offset);
- pageIndicatorLandGutterRightNavBarPx = res.getDimensionPixelSize(
- R.dimen.dynamic_grid_page_indicator_gutter_width_right_nav_bar);
defaultPageSpacingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_workspace_page_spacing);
topWorkspacePadding =
@@ -192,13 +197,25 @@
workspaceSpringLoadedBottomSpace =
res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
+ workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
+
hotseatBarTopPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
hotseatBarBottomPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding);
- hotseatBarHeightPx = hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx +
- res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height);
- hotseatLandGutterPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_land_gutter_width);
+ hotseatBarLeftNavBarRightPaddingPx = res.getDimensionPixelSize(
+ R.dimen.dynamic_grid_hotseat_land_left_nav_bar_right_padding);
+ hotseatBarRightNavBarRightPaddingPx = res.getDimensionPixelSize(
+ R.dimen.dynamic_grid_hotseat_land_right_nav_bar_right_padding);
+ hotseatBarHeightPx = isVerticalBarLayout()
+ ? res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height)
+ : res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height)
+ + hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx;
+
+ hotseatLandLeftNavBarGutterPx = res.getDimensionPixelSize(
+ R.dimen.dynamic_grid_hotseat_land_left_nav_bar_gutter_width);
+ hotseatLandRightNavBarGutterPx = res.getDimensionPixelSize(
+ R.dimen.dynamic_grid_hotseat_land_right_nav_bar_gutter_width);
// Determine sizes.
widthPx = width;
@@ -259,45 +276,51 @@
private void computeAllAppsButtonSize(Context context) {
Resources res = context.getResources();
float padding = res.getInteger(R.integer.config_allAppsButtonPaddingPercent) / 100f;
- allAppsButtonVisualSize = (int) (hotseatIconSizePx * (1 - padding)) - context.getResources()
+ allAppsButtonVisualSize = (int) (iconSizePx * (1 - padding)) - context.getResources()
.getDimensionPixelSize(R.dimen.all_apps_button_scale_down);
}
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) {
- iconSizePx = (int) (Utilities.pxFromDp(inv.iconSize, dm) * scale);
+ private void updateIconSize(float scale, Resources res, DisplayMetrics dm) {
+ float invIconSizePx = isVerticalBarLayout() ? inv.landscapeIconSize : inv.iconSize;
+ iconSizePx = (int) (Utilities.pxFromDp(invIconSizePx, dm) * scale);
iconTextSizePx = (int) (Utilities.pxFromSp(inv.iconTextSize, dm) * scale);
- iconDrawablePaddingPx = drawablePadding;
- hotseatIconSizePx = (int) (Utilities.pxFromDp(inv.hotseatIconSize, dm) * scale);
+ iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * scale);
+
+ // All apps
+ allAppsIconTextSizePx = iconTextSizePx;
allAppsIconSizePx = iconSizePx;
allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
- allAppsIconTextSizePx = iconTextSizePx;
+ allAppsCellHeightPx = getCellSize().y;
- cellWidthPx = iconSizePx;
+ if (isVerticalBarLayout()) {
+ // Always hide the Workspace text with vertical bar layout.
+ iconTextSizePx = 0;
+ allAppsCellHeightPx += Utilities.calculateTextHeight(allAppsIconTextSizePx);
+ }
+
+ cellWidthPx = iconSizePx + iconDrawablePaddingPx;
cellHeightPx = iconSizePx + iconDrawablePaddingPx
+ Utilities.calculateTextHeight(iconTextSizePx);
// Hotseat
- hotseatCellWidthPx = iconSizePx;
- hotseatCellHeightPx = iconSizePx;
+ hotseatCellHeightPx = iconSizePx + iconDrawablePaddingPx;
if (!isVerticalBarLayout()) {
int expectedWorkspaceHeight = availableHeightPx - hotseatBarHeightPx
- - pageIndicatorHeightPx - topWorkspacePadding;
+ - pageIndicatorSizePx - topWorkspacePadding;
float minRequiredHeight = dropTargetBarSizePx + workspaceSpringLoadedBottomSpace;
workspaceSpringLoadShrinkFactor = Math.min(
res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f,
@@ -308,7 +331,7 @@
}
// Folder icon
- folderBackgroundOffset = -edgeMarginPx;
+ folderBackgroundOffset = -iconDrawablePaddingPx;
folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
folderIconPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding);
}
@@ -401,22 +424,25 @@
/**
* Returns the workspace padding in the specified orientation.
- * Note that it assumes that while in verticalBarLayout, the nav bar is on the right, as such
- * this value is not reliable.
- * Use {@link #getTotalWorkspacePadding()} instead.
*/
public Rect getWorkspacePadding(Rect recycle) {
Rect padding = recycle == null ? new Rect() : recycle;
if (isVerticalBarLayout()) {
if (mInsets.left > 0) {
- padding.set(mInsets.left + pageIndicatorLandGutterLeftNavBarPx, 0,
- hotseatBarHeightPx + hotseatLandGutterPx - mInsets.left, 2 * edgeMarginPx);
+ padding.set(mInsets.left + pageIndicatorLandGutterPx,
+ 0,
+ hotseatBarHeightPx + hotseatLandLeftNavBarGutterPx
+ + hotseatBarLeftNavBarRightPaddingPx - mInsets.left,
+ edgeMarginPx);
} else {
- padding.set(pageIndicatorLandGutterRightNavBarPx, 0,
- hotseatBarHeightPx + hotseatLandGutterPx, 2 * edgeMarginPx);
+ padding.set(pageIndicatorLandGutterPx,
+ 0,
+ hotseatBarHeightPx + hotseatLandRightNavBarGutterPx
+ + hotseatBarRightNavBarRightPaddingPx,
+ edgeMarginPx);
}
} else {
- int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx;
+ int paddingBottom = hotseatBarHeightPx + pageIndicatorSizePx;
if (isTablet) {
// Pad the left and right of the workspace to ensure consistent spacing
// between all icons
@@ -458,7 +484,7 @@
return new Rect(mInsets.left,
mInsets.top + dropTargetBarSizePx + edgeMarginPx,
mInsets.left + availableWidthPx,
- mInsets.top + availableHeightPx - hotseatBarHeightPx - pageIndicatorHeightPx -
+ mInsets.top + availableHeightPx - hotseatBarHeightPx - pageIndicatorSizePx -
edgeMarginPx);
}
}
@@ -522,7 +548,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
@@ -548,7 +574,12 @@
lp.gravity = Gravity.RIGHT;
lp.width = hotseatBarHeightPx + mInsets.left + mInsets.right;
lp.height = LayoutParams.MATCH_PARENT;
- hotseat.getLayout().setPadding(mInsets.left, mInsets.top, mInsets.right,
+
+ int paddingRight = mInsets.left > 0
+ ? hotseatBarLeftNavBarRightPaddingPx
+ : hotseatBarRightNavBarRightPaddingPx;
+
+ hotseat.getLayout().setPadding(mInsets.left, mInsets.top, mInsets.right + paddingRight,
workspacePadding.bottom);
} else if (isTablet) {
// Pad the hotseat with the workspace padding calculated above
@@ -576,17 +607,15 @@
lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
if (isVerticalBarLayout()) {
if (mInsets.left > 0) {
- lp.leftMargin = mInsets.left + pageIndicatorLandGutterLeftNavBarPx -
- lp.width - pageIndicatorLandWorkspaceOffsetPx;
- } else if (mInsets.right > 0) {
- lp.leftMargin = pageIndicatorLandGutterRightNavBarPx - lp.width -
- pageIndicatorLandWorkspaceOffsetPx;
+ lp.leftMargin = mInsets.left;
+ } else {
+ lp.leftMargin = pageIndicatorLandWorkspaceOffsetPx;
}
lp.bottomMargin = workspacePadding.bottom;
} else {
// Put the page indicators above the hotseat
lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
- lp.height = pageIndicatorHeightPx;
+ lp.height = pageIndicatorSizePx;
lp.bottomMargin = hotseatBarHeightPx + mInsets.bottom;
}
pageIndicator.setLayoutParams(lp);
@@ -605,6 +634,12 @@
overviewMode.setLayoutParams(lp);
}
+ // Layout the AllAppsRecyclerView
+ View view = launcher.findViewById(R.id.apps_list_view);
+ int paddingLeftRight = hasVerticalBarLayout ? 0 : edgeMarginPx;
+ view.setPadding(paddingLeftRight, view.getPaddingTop(), paddingLeftRight,
+ view.getPaddingBottom());
+
if (notifyListeners) {
for (int i = mListeners.size() - 1; i >= 0; i--) {
mListeners.get(i).onLauncherLayoutChanged();
@@ -648,9 +683,8 @@
}
// In landscape, we match the width of the workspace
- int padding = (pageIndicatorLandGutterRightNavBarPx +
- hotseatBarHeightPx + hotseatLandGutterPx + mInsets.left) / 2;
- return new int[]{ padding, padding };
+ Rect padding = getWorkspacePadding(null);
+ return new int[] { padding.left - mInsets.left, padding.right + mInsets.left};
}
public boolean shouldIgnoreLongPressToOverview(float touchX) {
@@ -659,4 +693,11 @@
boolean touchedRhsEdge = mInsets.right == 0 && touchX > (widthPx - edgeMarginPx);
return !inMultiWindowMode && (touchedLhsEdge || touchedRhsEdge);
}
+
+ private static Context getContext(Context c, int orientation) {
+ Configuration context = new Configuration(c.getResources().getConfiguration());
+ context.orientation = orientation;
+ return c.createConfigurationContext(context);
+
+ }
}
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index 199baaf..1272e0a 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -36,8 +36,6 @@
public class FastBitmapDrawable extends Drawable {
- private static final int[] STATE_PRESSED = new int[] {android.R.attr.state_pressed};
-
private static final float PRESSED_BRIGHTNESS = 100f / 255f;
private static final float DISABLED_DESATURATION = 1f;
private static final float DISABLED_BRIGHTNESS = 0.5f;
@@ -107,17 +105,6 @@
@Override
public void draw(Canvas canvas) {
- drawInternal(canvas);
- }
-
- public void drawWithBrightness(Canvas canvas, float brightness) {
- float oldBrightness = getBrightness();
- setBrightness(brightness);
- drawInternal(canvas);
- setBrightness(oldBrightness);
- }
-
- protected void drawInternal(Canvas canvas) {
canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
}
@@ -185,6 +172,11 @@
}
@Override
+ public ColorFilter getColorFilter() {
+ return mPaint.getColorFilter();
+ }
+
+ @Override
protected boolean onStateChange(int[] state) {
boolean isPressed = false;
for (int s : state) {
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index ab82c98..af3abeb 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -151,7 +151,6 @@
mLauncher.setAllAppsButton(allAppsButton);
allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
allAppsButton.setOnClickListener(mLauncher);
- allAppsButton.setOnLongClickListener(mLauncher);
allAppsButton.setOnFocusChangeListener(mLauncher.mFocusHandler);
}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index ad816af..383e6ef 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -170,7 +170,11 @@
}
public Drawable getFullResIcon(LauncherActivityInfo info) {
- return mIconProvider.getIcon(info, mIconDpi);
+ return getFullResIcon(info, true);
+ }
+
+ public Drawable getFullResIcon(LauncherActivityInfo info, boolean flattenDrawable) {
+ return mIconProvider.getIcon(info, mIconDpi, flattenDrawable);
}
protected Bitmap makeDefaultIcon(UserHandle user) {
@@ -749,7 +753,7 @@
}
private static final class IconDB extends SQLiteCacheHelper {
- private final static int DB_VERSION = 14;
+ private final static int DB_VERSION = 16;
private final static int RELEASE_VERSION = DB_VERSION +
(FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ? 0 : 1);
diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java
index a5d3990..6872515 100644
--- a/src/com/android/launcher3/IconProvider.java
+++ b/src/com/android/launcher3/IconProvider.java
@@ -24,8 +24,11 @@
return mSystemState;
}
-
- public Drawable getIcon(LauncherActivityInfo info, int iconDpi) {
+ /**
+ * @param flattenDrawable true if the caller does not care about the specification of the
+ * original icon as long as the flattened version looks the same.
+ */
+ public Drawable getIcon(LauncherActivityInfo info, int iconDpi, boolean flattenDrawable) {
return info.getIcon(iconDpi);
}
}
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index b136e7d..0370777 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -217,6 +217,10 @@
return info == null ? null : (ShortcutInfo) info.getItemInfo().first;
}
+ public static ShortcutInfo fromActivityInfo(LauncherActivityInfo info, Context context) {
+ return (ShortcutInfo) (new PendingInstallShortcutInfo(info, context).getItemInfo().first);
+ }
+
public static void queueShortcut(ShortcutInfoCompat info, Context context) {
queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, context), context);
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index d224615..d7bebd1 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -76,6 +76,7 @@
public int numFolderRows;
public int numFolderColumns;
public float iconSize;
+ public float landscapeIconSize;
public int iconBitmapSize;
public int fillResIconDpi;
public float iconTextSize;
@@ -84,8 +85,6 @@
* Number of icons inside the hotseat area.
*/
public int numHotseatIcons;
- float hotseatIconSize;
- public float hotseatScale;
int defaultLayoutId;
public DeviceProfile landscapeProfile;
@@ -99,12 +98,12 @@
public InvariantDeviceProfile(InvariantDeviceProfile p) {
this(p.name, p.minWidthDps, p.minHeightDps, p.numRows, p.numColumns,
p.numFolderRows, p.numFolderColumns, p.minAllAppsPredictionColumns,
- p.iconSize, p.iconTextSize, p.numHotseatIcons, p.hotseatIconSize,
+ p.iconSize, p.landscapeIconSize, p.iconTextSize, p.numHotseatIcons,
p.defaultLayoutId);
}
InvariantDeviceProfile(String n, float w, float h, int r, int c, int fr, int fc, int maapc,
- float is, float its, int hs, float his, int dlId) {
+ float is, float lis, float its, int hs, int dlId) {
name = n;
minWidthDps = w;
minHeightDps = h;
@@ -114,12 +113,10 @@
numFolderColumns = fc;
minAllAppsPredictionColumns = maapc;
iconSize = is;
+ landscapeIconSize = lis;
iconTextSize = its;
numHotseatIcons = hs;
- hotseatIconSize = his;
defaultLayoutId = dlId;
-
- hotseatScale = hotseatIconSize / iconSize;
}
@TargetApi(23)
@@ -152,17 +149,15 @@
minAllAppsPredictionColumns = closestProfile.minAllAppsPredictionColumns;
iconSize = interpolatedDeviceProfileOut.iconSize;
+ landscapeIconSize = interpolatedDeviceProfileOut.landscapeIconSize;
iconBitmapSize = Utilities.pxFromDp(iconSize, dm);
iconTextSize = interpolatedDeviceProfileOut.iconTextSize;
- hotseatIconSize = interpolatedDeviceProfileOut.hotseatIconSize;
fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
// If the partner customization apk contains any grid overrides, apply them
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, dm);
- hotseatScale = hotseatIconSize / iconSize;
-
Point realSize = new Point();
display.getRealSize(realSize);
// The real size never changes. smallSide and largeSide will remain the
@@ -210,9 +205,9 @@
a.getInt(R.styleable.InvariantDeviceProfile_numFolderColumns, numColumns),
a.getInt(R.styleable.InvariantDeviceProfile_minAllAppsPredictionColumns, numColumns),
iconSize,
+ a.getFloat(R.styleable.InvariantDeviceProfile_landscapeIconSize, iconSize),
a.getFloat(R.styleable.InvariantDeviceProfile_iconTextSize, 0),
a.getInt(R.styleable.InvariantDeviceProfile_numHotseatIcons, numColumns),
- a.getFloat(R.styleable.InvariantDeviceProfile_hotseatIconSize, iconSize),
a.getResourceId(R.styleable.InvariantDeviceProfile_defaultLayoutId, 0)));
a.recycle();
}
@@ -304,14 +299,14 @@
private void add(InvariantDeviceProfile p) {
iconSize += p.iconSize;
+ landscapeIconSize += p.landscapeIconSize;
iconTextSize += p.iconTextSize;
- hotseatIconSize += p.hotseatIconSize;
}
private InvariantDeviceProfile multiply(float w) {
iconSize *= w;
+ landscapeIconSize *= w;
iconTextSize *= w;
- hotseatIconSize *= w;
return this;
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index dd0d2b8..26c5c9d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -79,7 +79,6 @@
import android.view.accessibility.AccessibilityManager;
import android.view.animation.OvershootInterpolator;
import android.view.inputmethod.InputMethodManager;
-import android.widget.TextView;
import android.widget.Toast;
import com.android.launcher3.DropTarget.DragObject;
@@ -126,6 +125,7 @@
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
+import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.TestingUtils;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
@@ -215,9 +215,9 @@
private static final int ACTIVITY_START_DELAY = 1000;
// How long to wait before the new-shortcut animation automatically pans the workspace
- private static int NEW_APPS_PAGE_MOVE_DELAY = 500;
- private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
- @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;
+ private static final int NEW_APPS_PAGE_MOVE_DELAY = 500;
+ private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
+ @Thunk static final int NEW_APPS_ANIMATION_DELAY = 500;
private final ExtractedColors mExtractedColors = new ExtractedColors();
@@ -231,7 +231,7 @@
private AppWidgetManagerCompat mAppWidgetManager;
private LauncherAppWidgetHost mAppWidgetHost;
- private int[] mTmpAddItemCellCoordinates = new int[2];
+ private final int[] mTmpAddItemCellCoordinates = new int[2];
@Thunk Hotseat mHotseat;
private ViewGroup mOverviewPanel;
@@ -261,15 +261,15 @@
private boolean mPaused = true;
private boolean mOnResumeNeedsLoad;
- private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();
- private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();
+ private final ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<>();
+ private final ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<>();
private ViewOnDrawExecutor mPendingExecutor;
private LauncherModel mModel;
private ModelWriter mModelWriter;
private IconCache mIconCache;
private LauncherAccessibilityDelegate mAccessibilityDelegate;
- private Handler mHandler = new Handler();
+ private final Handler mHandler = new Handler();
private boolean mIsResumeFromActionScreenOff;
private boolean mHasFocus = false;
@@ -283,7 +283,7 @@
// match the sensor state.
private static final int RESTORE_SCREEN_ORIENTATION_DELAY = 500;
- private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();
+ private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<>();
// We only want to get the SharedPreferences once since it does an FS stat each time we get
// it from the context.
@@ -296,8 +296,8 @@
// the press state and keep this reference to reset the press state when we return to launcher.
private BubbleTextView mWaitingForResume;
- protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =
- new HashMap<String, CustomAppWidget>();
+ protected static final HashMap<String, CustomAppWidget> sCustomAppWidgets =
+ new HashMap<>();
static {
if (TestingUtils.ENABLE_CUSTOM_WIDGET_TEST) {
@@ -310,7 +310,7 @@
// simply unregister this runnable.
private Runnable mExitSpringLoadedModeRunnable;
- @Thunk Runnable mBuildLayersRunnable = new Runnable() {
+ @Thunk final Runnable mBuildLayersRunnable = new Runnable() {
public void run() {
if (mWorkspace != null) {
mWorkspace.buildPageHardwareLayers();
@@ -470,9 +470,8 @@
// Listen for broadcasts screen off
registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
- if (Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)) {
- activateLightSystemBars(true, true, true);
- }
+ getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
+ Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
}
@Override
@@ -519,36 +518,6 @@
}
}
- /**
- * Sets the status and/or nav bar to be light or not. Light status bar means dark icons.
- * @param isLight make sure the system bar is light.
- * @param statusBar if true, make the status bar theme match the isLight param.
- * @param navBar if true, make the nav bar theme match the isLight param.
- */
- public void activateLightSystemBars(boolean isLight, boolean statusBar, boolean navBar) {
- int oldSystemUiFlags = getWindow().getDecorView().getSystemUiVisibility();
- int newSystemUiFlags = oldSystemUiFlags;
- if (isLight) {
- if (statusBar) {
- newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
- }
- if (navBar && Utilities.isAtLeastO()) {
- newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
- }
- } else {
- if (statusBar) {
- newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
- }
- if (navBar && Utilities.isAtLeastO()) {
- newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
- }
- }
-
- if (newSystemUiFlags != oldSystemUiFlags) {
- getWindow().getDecorView().setSystemUiVisibility(newSystemUiFlags);
- }
- }
-
private LauncherCallbacks mLauncherCallbacks;
public void onPostCreate(Bundle savedInstanceState) {
@@ -979,8 +948,7 @@
// Don't update the predicted apps if the user is returning to launcher in the apps
// view after launching an app, as they may be depending on the UI to be static to
// switch to another app, otherwise, if it was
- showAppsView(false /* animated */, !launchedFromApp /* updatePredictedApps */,
- mAppsView.shouldRestoreImeState() /* focusSearchBar */);
+ showAppsView(false /* animated */, !launchedFromApp /* updatePredictedApps */);
} else if (mOnResumeState == State.WIDGETS) {
showWidgetsView(false, false);
}
@@ -1094,13 +1062,13 @@
public interface CustomContentCallbacks {
// Custom content is completely shown. {@code fromResume} indicates whether this was caused
// by a onResume or by scrolling otherwise.
- public void onShow(boolean fromResume);
+ void onShow(boolean fromResume);
// Custom content is completely hidden
- public void onHide();
+ void onHide();
// Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).
- public void onScrollProgressChanged(float progress);
+ void onScrollProgressChanged(float progress);
// Indicates whether the user is allowed to scroll away from the custom content.
boolean isScrollingAllowed();
@@ -1111,28 +1079,28 @@
/**
* Touch interaction leading to overscroll has begun
*/
- public void onScrollInteractionBegin();
+ void onScrollInteractionBegin();
/**
* Touch interaction related to overscroll has ended
*/
- public void onScrollInteractionEnd();
+ void onScrollInteractionEnd();
/**
* Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost
* screen (or in the case of RTL, the rightmost screen).
*/
- public void onScrollChange(float progress, boolean rtl);
+ void onScrollChange(float progress, boolean rtl);
/**
* Called when the launcher is ready to use the overlay
* @param callbacks A set of callbacks provided by Launcher in relation to the overlay
*/
- public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks);
+ void setOverlayCallbacks(LauncherOverlayCallbacks callbacks);
}
public interface LauncherOverlayCallbacks {
- public void onScrollChanged(float progress);
+ void onScrollChanged(float progress);
}
class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {
@@ -1316,7 +1284,7 @@
mDragController.addDragListener(mWorkspace);
// Get the search/delete/uninstall bar
- mDropTargetBar = (DropTargetBar) mDragLayer.findViewById(R.id.drop_target_bar);
+ mDropTargetBar = mDragLayer.findViewById(R.id.drop_target_bar);
// Setup Apps and Widgets
mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);
@@ -1414,7 +1382,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;
@@ -1639,7 +1606,6 @@
}
}
});
- return;
}
});
}
@@ -1776,8 +1742,9 @@
// as slow logic in the callbacks eat into the time the scroller expects for the snapToPage
// animation.
if (isActionMain) {
- boolean callbackAllowsMoveToDefaultScreen = mLauncherCallbacks != null ?
- mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;
+ boolean callbackAllowsMoveToDefaultScreen =
+ mLauncherCallbacks == null || mLauncherCallbacks
+ .shouldMoveToDefaultScreenOnHomeIntent();
if (shouldMoveToDefaultScreen && !mWorkspace.isTouchActive()
&& callbackAllowsMoveToDefaultScreen) {
@@ -2351,18 +2318,7 @@
if (!isAppsViewVisible()) {
getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
ControlType.ALL_APPS_BUTTON);
- showAppsView(true /* animated */, true /* updatePredictedApps */,
- false /* focusSearchBar */);
- }
- }
-
- protected void onLongClickAllAppsButton(View v) {
- if (LOGD) Log.d(TAG, "onLongClickAllAppsButton");
- if (!isAppsViewVisible()) {
- getUserEventDispatcher().logActionOnControl(Action.Touch.LONGPRESS,
- ControlType.ALL_APPS_BUTTON);
- showAppsView(true /* animated */,
- true /* updatePredictedApps */, true /* focusSearchBar */);
+ showAppsView(true /* animated */, true /* updatePredictedApps */);
}
}
@@ -2669,9 +2625,9 @@
if (Utilities.ATLEAST_MARSHMALLOW) {
int left = 0, top = 0;
int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
- if (v instanceof TextView) {
+ if (v instanceof BubbleTextView) {
// Launch from center of icon, not entire view
- Drawable icon = Workspace.getTextViewIcon((TextView) v);
+ Drawable icon = ((BubbleTextView) v).getIcon();
if (icon != null) {
Rect bounds = icon.getBounds();
left = (width - bounds.width()) / 2;
@@ -2750,13 +2706,6 @@
if (isWorkspaceLocked()) return false;
if (mState != State.WORKSPACE) return false;
- if ((FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && v instanceof PageIndicator) ||
- (v == mAllAppsButton && mAllAppsButton != null)) {
- onLongClickAllAppsButton(v);
- return true;
- }
-
-
boolean ignoreLongPressToOverview =
mDeviceProfile.shouldIgnoreLongPressToOverview(mLastDispatchTouchEventX);
@@ -2956,13 +2905,12 @@
/**
* Shows the apps view.
*/
- public void showAppsView(boolean animated, boolean updatePredictedApps,
- boolean focusSearchBar) {
+ public void showAppsView(boolean animated, boolean updatePredictedApps) {
markAppsViewShown();
if (updatePredictedApps) {
tryAndUpdatePredictedApps();
}
- showAppsOrWidgets(State.APPS, animated, focusSearchBar);
+ showAppsOrWidgets(State.APPS, animated);
}
/**
@@ -2973,7 +2921,7 @@
if (resetPageToZero) {
mWidgetsView.scrollToTop();
}
- showAppsOrWidgets(State.WIDGETS, animated, false);
+ showAppsOrWidgets(State.WIDGETS, animated);
mWidgetsView.post(new Runnable() {
@Override
@@ -2990,7 +2938,7 @@
*/
// TODO: calling method should use the return value so that when {@code false} is returned
// the workspace transition doesn't fall into invalid state.
- private boolean showAppsOrWidgets(State toState, boolean animated, boolean focusSearchBar) {
+ private boolean showAppsOrWidgets(State toState, boolean animated) {
if (!(mState == State.WORKSPACE ||
mState == State.APPS_SPRING_LOADED ||
mState == State.WIDGETS_SPRING_LOADED ||
@@ -3008,7 +2956,7 @@
}
if (toState == State.APPS) {
- mStateTransitionAnimation.startAnimationToAllApps(animated, focusSearchBar);
+ mStateTransitionAnimation.startAnimationToAllApps(animated);
} else {
mStateTransitionAnimation.startAnimationToWidgets(animated);
}
@@ -3081,8 +3029,7 @@
public void exitSpringLoadedDragMode() {
if (mState == State.APPS_SPRING_LOADED) {
- showAppsView(true /* animated */,
- false /* updatePredictedApps */, false /* focusSearchBar */);
+ showAppsView(true /* animated */, false /* updatePredictedApps */);
} else if (mState == State.WIDGETS_SPRING_LOADED) {
showWidgetsView(true, false);
} else if (mState == State.WORKSPACE_SPRING_LOADED) {
@@ -3248,7 +3195,7 @@
orderedScreenIds.indexOf(Workspace.FIRST_SCREEN_ID) != 0) {
orderedScreenIds.remove(Workspace.FIRST_SCREEN_ID);
orderedScreenIds.add(0, Workspace.FIRST_SCREEN_ID);
- mModel.updateWorkspaceScreenOrder(this, orderedScreenIds);
+ LauncherModel.updateWorkspaceScreenOrder(this, orderedScreenIds);
} else if (!FeatureFlags.QSB_ON_FIRST_SCREEN && orderedScreenIds.isEmpty()) {
// If there are no screens, we need to have an empty screen
mWorkspace.addExtraEmptyScreen();
@@ -3335,7 +3282,7 @@
// Get the list of added items and intersect them with the set of items here
final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
- final Collection<Animator> bounceAnims = new ArrayList<Animator>();
+ final Collection<Animator> bounceAnims = new ArrayList<>();
final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();
Workspace workspace = mWorkspace;
long newItemsScreenId = -1;
@@ -3719,7 +3666,7 @@
* multiple calls to bind the same list.)
*/
@Thunk ArrayList<AppInfo> mTmpAppsList;
- private Runnable mBindAllApplicationsRunnable = new Runnable() {
+ private final Runnable mBindAllApplicationsRunnable = new Runnable() {
public void run() {
bindAllApplications(mTmpAppsList);
mTmpAppsList = null;
@@ -3923,7 +3870,7 @@
}
}
- private Runnable mBindAllWidgetsRunnable = new Runnable() {
+ private final Runnable mBindAllWidgetsRunnable = new Runnable() {
public void run() {
bindAllWidgets(mAllWidgets);
}
@@ -3994,7 +3941,7 @@
}
private boolean shouldShowDiscoveryBounce() {
- if (mState != mState.WORKSPACE) {
+ if (mState != State.WORKSPACE) {
return false;
}
if (mLauncherCallbacks != null && mLauncherCallbacks.shouldShowDiscoveryBounce()) {
@@ -4003,10 +3950,7 @@
if (!mIsResumeFromActionScreenOff) {
return false;
}
- if (mSharedPrefs.getBoolean(APPS_VIEW_SHOWN, false)) {
- return false;
- }
- return true;
+ return !mSharedPrefs.getBoolean(APPS_VIEW_SHOWN, false);
}
protected void moveWorkspaceToDefaultScreen() {
@@ -4095,7 +4039,7 @@
switch (keyCode) {
case KeyEvent.KEYCODE_A:
if (mState == State.WORKSPACE) {
- showAppsView(true, true, false);
+ showAppsView(true, true);
return true;
}
break;
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index 85467e0..e7349f0 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -127,12 +127,8 @@
/**
* Starts an animation to the apps view.
- *
- * @param startSearchAfterTransition Immediately starts app search after the transition to
- * All Apps is completed.
*/
- public void startAnimationToAllApps(
- final boolean animated, final boolean startSearchAfterTransition) {
+ public void startAnimationToAllApps(final boolean animated) {
final AllAppsContainerView toView = mLauncher.getAppsView();
final View buttonView = mLauncher.getStartViewForAllAppsRevealAnimation();
PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
@@ -156,9 +152,6 @@
@Override
void onTransitionComplete() {
mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
- if (startSearchAfterTransition) {
- toView.startAppsSearch();
- }
}
};
int animType = CIRCULAR_REVEAL;
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index 0902b20..b7b75f8 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -26,7 +26,6 @@
import android.preference.PreferenceFragment;
import android.provider.Settings;
import android.provider.Settings.System;
-import android.support.v4.os.BuildCompat;
import com.android.launcher3.graphics.IconShapeOverride;
@@ -85,7 +84,7 @@
}
Preference iconBadgingPref = findPreference(ICON_BADGING_PREFERENCE_KEY);
- if (!BuildCompat.isAtLeastO()) {
+ if (!Utilities.isAtLeastO()) {
getPreferenceScreen().removePreference(
findPreference(SessionCommitReceiver.ADD_ICON_PREFERENCE_KEY));
getPreferenceScreen().removePreference(iconBadgingPref);
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index f8742f8..fd708c0 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -120,7 +120,9 @@
// 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 = mContainerType == CellLayout.WORKSPACE
+ ? profile.workspaceCellPaddingXPx
+ : (int) (profile.edgeMarginPx / 2f);
child.setPadding(cellPaddingX, cellPaddingY, cellPaddingX, 0);
}
} else {
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index c2987f8..9100fe2 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -38,7 +38,6 @@
import android.os.DeadObjectException;
import android.os.PowerManager;
import android.os.TransactionTooLargeException;
-import android.support.v4.os.BuildCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@@ -86,7 +85,7 @@
private static final Matrix sInverseMatrix = new Matrix();
public static boolean isAtLeastO() {
- return BuildCompat.isAtLeastO();
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
}
public static final boolean ATLEAST_NOUGAT_MR1 =
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index f66995f..ad1be7e 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 = 8;
private static final String TABLE_NAME = "shortcut_and_widget_previews";
private static final String COLUMN_COMPONENT = "componentName";
@@ -432,14 +432,17 @@
private RectF drawBoxWithShadow(Canvas c, int width, int height) {
Resources res = mContext.getResources();
- float shadowBlur = res.getDimension(R.dimen.widget_preview_shadow_blur);
- float keyShadowDistance = res.getDimension(R.dimen.widget_preview_key_shadow_distance);
- float corner = res.getDimension(R.dimen.widget_preview_corner_radius);
- RectF bounds = new RectF(shadowBlur, shadowBlur,
- width - shadowBlur, height - shadowBlur - keyShadowDistance);
- ShadowGenerator.drawShadow(c, bounds, Color.WHITE, shadowBlur, keyShadowDistance, corner);
- return bounds;
+ ShadowGenerator.Builder builder = new ShadowGenerator.Builder(Color.WHITE);
+ builder.shadowBlur = res.getDimension(R.dimen.widget_preview_shadow_blur);
+ builder.radius = res.getDimension(R.dimen.widget_preview_corner_radius);
+ builder.keyShadowDistance = res.getDimension(R.dimen.widget_preview_key_shadow_distance);
+
+ builder.bounds.set(builder.shadowBlur, builder.shadowBlur,
+ width - builder.shadowBlur,
+ height - builder.shadowBlur - builder.keyShadowDistance);
+ builder.drawShadow(c);
+ return builder.bounds;
}
private Bitmap generateShortcutPreview(BaseActivity launcher, ShortcutConfigActivityInfo info,
@@ -468,7 +471,7 @@
RectF boxRect = drawBoxWithShadow(c, size, size);
Bitmap icon = LauncherIcons.createScaledBitmapWithoutShadow(
- mutateOnMainThread(info.getFullResIcon(mIconCache)), mContext, Build.VERSION_CODES.O);
+ mutateOnMainThread(info.getFullResIcon(mIconCache)), mContext, 0);
Rect src = new Rect(0, 0, icon.getWidth(), icon.getHeight());
boxRect.set(0, 0, iconSize, iconSize);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 3fe7875..767e332 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -51,7 +51,6 @@
import android.view.accessibility.AccessibilityManager;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
-import android.widget.TextView;
import android.widget.Toast;
import com.android.launcher3.Launcher.CustomContentCallbacks;
import com.android.launcher3.Launcher.LauncherOverlay;
@@ -71,6 +70,7 @@
import com.android.launcher3.dragndrop.SpringLoadedDragController;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.popup.PopupContainerWithArrow;
@@ -254,7 +254,7 @@
public static final int REORDER_TIMEOUT = 350;
private final Alarm mFolderCreationAlarm = new Alarm();
private final Alarm mReorderAlarm = new Alarm();
- private FolderIcon.PreviewBackground mFolderCreateBg;
+ private PreviewBackground mFolderCreateBg;
private FolderIcon mDragOverFolderIcon = null;
private boolean mCreateUserFolderOnDrop = false;
private boolean mAddToExistingFolderOnDrop = false;
@@ -305,8 +305,6 @@
private boolean mForceDrawAdjacentPages = false;
// Total over scrollX in the overlay direction.
private float mOverlayTranslation;
- private int mFirstPageScrollX;
- private boolean mIgnoreQsbScroll;
// Handles workspace state transitions
private final WorkspaceStateTransitionAnimation mStateTransitionAnimation;
@@ -1739,32 +1737,6 @@
mWallpaperOffset.jumpToFinal();
}
super.onLayout(changed, left, top, right, bottom);
- mFirstPageScrollX = getScrollForPage(0);
-
- final LayoutTransition transition = getLayoutTransition();
- // If the transition is running defer updating max scroll, as some empty pages could
- // still be present, and a max scroll change could cause sudden jumps in scroll.
- if (transition != null && transition.isRunning()) {
- transition.addTransitionListener(new LayoutTransition.TransitionListener() {
-
- @Override
- public void startTransition(LayoutTransition transition, ViewGroup container,
- View view, int transitionType) {
- mIgnoreQsbScroll = true;
- }
-
- @Override
- public void endTransition(LayoutTransition transition, ViewGroup container,
- View view, int transitionType) {
- // Wait until all transitions are complete.
- if (!transition.isRunning()) {
- mIgnoreQsbScroll = false;
- transition.removeTransitionListener(this);
- mFirstPageScrollX = getScrollForPage(0);
- }
- }
- });
- }
updatePageAlphaValues();
}
@@ -2110,27 +2082,9 @@
}
}
- /**
- * Returns the drawable for the given text view.
- */
- public static Drawable getTextViewIcon(TextView tv) {
- final Drawable[] drawables = tv.getCompoundDrawables();
- for (int i = 0; i < drawables.length; i++) {
- if (drawables[i] != null) {
- return drawables[i];
- }
- }
- return null;
- }
-
public void startDrag(CellLayout.CellInfo cellInfo, DragOptions options) {
View child = cellInfo.cell;
- // Make sure the drag was started by a long press as opposed to a long click.
- if (!child.isInTouchMode()) {
- return;
- }
-
mDragInfo = cellInfo;
child.setVisibility(INVISIBLE);
@@ -2407,7 +2361,7 @@
// In order to keep everything continuous, we hand off the currently rendered
// folder background to the newly created icon. This preserves animation state.
fi.setFolderBackground(mFolderCreateBg);
- mFolderCreateBg = new FolderIcon.PreviewBackground();
+ mFolderCreateBg = new PreviewBackground();
fi.performCreateAnimation(destInfo, v, sourceInfo, dragView, folderLocation, scale,
postAnimationRunnable);
} else {
@@ -3088,7 +3042,7 @@
final int cellX;
final int cellY;
- final FolderIcon.PreviewBackground bg = new FolderIcon.PreviewBackground();
+ final PreviewBackground bg = new PreviewBackground();
public FolderCreationAlarmListener(CellLayout layout, int cellX, int cellY) {
this.layout = layout;
@@ -3548,7 +3502,7 @@
}
}
if ((d.cancelled || (beingCalledAfterUninstall && !mUninstallSuccessful))
- && mDragInfo.cell != null) {
+ && mDragInfo != null && mDragInfo.cell != null) {
mDragInfo.cell.setVisibility(VISIBLE);
}
mDragInfo = null;
@@ -3897,7 +3851,7 @@
updates.contains(info)) {
ShortcutInfo si = (ShortcutInfo) info;
BubbleTextView shortcut = (BubbleTextView) v;
- Drawable oldIcon = getTextViewIcon(shortcut);
+ Drawable oldIcon = shortcut.getIcon();
boolean oldPromiseState = (oldIcon instanceof PreloadIconDrawable)
&& ((PreloadIconDrawable) oldIcon).hasNotCompleted();
shortcut.applyFromShortcutInfo(si, si.isPromise() != oldPromiseState);
@@ -4121,8 +4075,8 @@
private boolean mRefreshPending;
- public DeferredWidgetRefresh(ArrayList<LauncherAppWidgetInfo> infos,
- LauncherAppWidgetHost host) {
+ DeferredWidgetRefresh(ArrayList<LauncherAppWidgetInfo> infos,
+ LauncherAppWidgetHost host) {
mInfos = infos;
mHost = host;
mHandler = new Handler();
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/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index c3df073..47b68a2 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -171,19 +171,19 @@
* Returns whether the view itself will handle the touch event or not.
*/
public boolean shouldContainerScroll(MotionEvent ev) {
- int[] point = new int[2];
- point[0] = (int) ev.getX();
- point[1] = (int) ev.getY();
- Utilities.mapCoordInSelfToDescendant(mAppsRecyclerView, this, point);
-
// IF the MotionEvent is inside the search box, and the container keeps on receiving
// touch input, container should move down.
if (mLauncher.getDragLayer().isEventOverView(mSearchContainer, ev)) {
return true;
}
+ int[] point = new int[2];
+ point[0] = (int) ev.getX();
+ point[1] = (int) ev.getY();
+ Utilities.mapCoordInSelfToDescendant(
+ mAppsRecyclerView.getScrollBar(), mLauncher.getDragLayer(), point);
// IF the MotionEvent is inside the thumb, container should not be pulled down.
- if (mAppsRecyclerView.getScrollBar().isNearThumb(point[0], point[1])) {
+ if (mAppsRecyclerView.getScrollBar().shouldBlockIntercept(point[0], point[1])) {
return false;
}
@@ -196,13 +196,6 @@
}
/**
- * Focuses the search field and begins an app search.
- */
- public void startAppsSearch() {
- mSearchUiManager.startAppsSearch();
- }
-
- /**
* Resets the state of AllApps.
*/
public void reset() {
@@ -306,10 +299,7 @@
@Override
public boolean onLongClick(final View v) {
- // Return early if this is not initiated from a touch
- if (!v.isInTouchMode()) return false;
// When we have exited all apps or are in transition, disregard long clicks
-
if (!mLauncher.isAppsViewVisible() ||
mLauncher.getWorkspace().isSwitchingState()) return false;
// Return if global dragging is not enabled or we are already dragging
@@ -372,10 +362,6 @@
targetParent.containerType = mAppsRecyclerView.getContainerType(v);
}
- public boolean shouldRestoreImeState() {
- return mSearchUiManager.shouldRestoreImeState();
- }
-
@Override
public void setInsets(Rect insets) {
DeviceProfile grid = mLauncher.getDeviceProfile();
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 9c7372f..1054a56 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.graphics.Point;
import android.support.animation.DynamicAnimation;
import android.support.animation.SpringAnimation;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
@@ -70,16 +69,13 @@
// A divider that separates the apps list and the search market button
public static final int VIEW_TYPE_SEARCH_MARKET_DIVIDER = 1 << 5;
- // The divider under the search field
- public static final int VIEW_TYPE_SEARCH_DIVIDER = 1 << 6;
// The divider that separates prediction icons from the app list
- public static final int VIEW_TYPE_PREDICTION_DIVIDER = 1 << 7;
- public static final int VIEW_TYPE_APPS_LOADING_DIVIDER = 1 << 8;
- public static final int VIEW_TYPE_DISCOVERY_ITEM = 1 << 9;
+ public static final int VIEW_TYPE_PREDICTION_DIVIDER = 1 << 6;
+ public static final int VIEW_TYPE_APPS_LOADING_DIVIDER = 1 << 7;
+ public static final int VIEW_TYPE_DISCOVERY_ITEM = 1 << 8;
// Common view type masks
- public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_SEARCH_DIVIDER
- | VIEW_TYPE_SEARCH_MARKET_DIVIDER
+ public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_SEARCH_MARKET_DIVIDER
| VIEW_TYPE_PREDICTION_DIVIDER;
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON
| VIEW_TYPE_PREDICTION_ICON;
@@ -298,8 +294,8 @@
icon.setLongPressTimeout(ViewConfiguration.getLongPressTimeout());
icon.setOnFocusChangeListener(mIconFocusListener);
- // Ensure the all apps icon height matches the workspace icons
- icon.getLayoutParams().height = getCellSize().y;
+ // Ensure the all apps icon height matches the workspace icons in portrait mode.
+ icon.getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx;
return new ViewHolder(icon);
case VIEW_TYPE_DISCOVERY_ITEM:
AppDiscoveryItemView appDiscoveryItemView = (AppDiscoveryItemView) mLayoutInflater
@@ -320,9 +316,6 @@
}
});
return new ViewHolder(searchMarketView);
- case VIEW_TYPE_SEARCH_DIVIDER:
- return new ViewHolder(mLayoutInflater.inflate(
- R.layout.all_apps_search_divider, parent, false));
case VIEW_TYPE_APPS_LOADING_DIVIDER:
View loadingDividerView = mLayoutInflater.inflate(
R.layout.all_apps_discovery_loading_divider, parent, false);
@@ -336,10 +329,6 @@
}
}
- private Point getCellSize() {
- return mLauncher.getDeviceProfile().getCellSize();
- }
-
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index b2a74ff..2b2fddc 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -72,7 +72,6 @@
super(context, attrs, defStyleAttr);
Resources res = getResources();
addOnItemTouchListener(this);
- mScrollbar.setDetachThumbOnFastScroll();
mEmptySearchBackgroundTopOffset = res.getDimensionPixelSize(
R.dimen.all_apps_empty_search_bg_top_offset);
}
@@ -110,7 +109,6 @@
RecyclerView.RecycledViewPool pool = getRecycledViewPool();
int approxRows = (int) Math.ceil(grid.availableHeightPx / grid.allAppsIconSizePx);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH, 1);
- pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER, 1);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET_DIVIDER, 1);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET, 1);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, approxRows * mNumAppsPerRow);
@@ -137,8 +135,6 @@
AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER,
AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET_DIVIDER);
putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
- AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER);
- putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET);
putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH);
@@ -164,7 +160,9 @@
*/
public void scrollToTop() {
// Ensure we reattach the scrollbar if it was previously detached while fast-scrolling
- mScrollbar.reattachThumbToScroll();
+ if (mScrollbar != null) {
+ mScrollbar.reattachThumbToScroll();
+ }
scrollToPosition(0);
}
@@ -356,7 +354,7 @@
}
@Override
- protected boolean supportsFastScrolling() {
+ public boolean supportsFastScrolling() {
// Only allow fast scrolling when the user is not searching, since the results are not
// grouped in a meaningful order
return !mApps.hasFilter();
@@ -376,7 +374,8 @@
if (position == NO_POSITION) {
return -1;
}
- return getCurrentScrollY(position, getLayoutManager().getDecoratedTop(child));
+ return getPaddingTop() +
+ getCurrentScrollY(position, getLayoutManager().getDecoratedTop(child));
}
public int getCurrentScrollY(int position, int offset) {
@@ -406,8 +405,7 @@
}
mCachedScrollPositions.put(position, y);
}
-
- return getPaddingTop() + y - offset;
+ return y - offset;
}
/**
@@ -416,7 +414,7 @@
*/
@Override
protected int getAvailableScrollHeight() {
- return getCurrentScrollY(mApps.getAdapterItems().size(), 0)
+ return getPaddingTop() + getCurrentScrollY(mApps.getAdapterItems().size(), 0)
- getHeight() + getPaddingBottom();
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index d79b0d19..4d112c6 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -28,6 +28,7 @@
import com.android.launcher3.graphics.ScrimView;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TouchController;
@@ -48,7 +49,7 @@
private static final boolean DBG = false;
private final Interpolator mWorkspaceAccelnterpolator = new AccelerateInterpolator(2f);
- private final Interpolator mHotseatAccelInterpolator = new AccelerateInterpolator(.5f);
+ private final Interpolator mHotseatAccelInterpolator = new AccelerateInterpolator(1.5f);
private final Interpolator mDecelInterpolator = new DecelerateInterpolator(3f);
private final Interpolator mFastOutSlowInInterpolator = new FastOutSlowInInterpolator();
private final VerticalPullDetector.ScrollInterpolator mScrollInterpolator
@@ -71,7 +72,6 @@
private final VerticalPullDetector mDetector;
private final ArgbEvaluator mEvaluator;
private final boolean mIsDarkTheme;
- private final boolean mIsWorkspaceDarkText;
// Animation in this class is controlled by a single variable {@link mProgress}.
// Visually, it represents top y coordinate of the all apps container if multiplied with
@@ -114,7 +114,6 @@
mEvaluator = new ArgbEvaluator();
mAllAppsBackgroundColor = Themes.getAttrColor(l, android.R.attr.colorPrimary);
mIsDarkTheme = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark);
- mIsWorkspaceDarkText = Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText);
}
@Override
@@ -227,9 +226,7 @@
Action.Direction.UP,
containerType);
}
- mLauncher.showAppsView(true /* animated */,
- false /* updatePredictedApps */,
- false /* focusSearchBar */);
+ mLauncher.showAppsView(true /* animated */, false /* updatePredictedApps */);
if (hasSpringAnimationHandler()) {
mSpringAnimationHandler.animateToFinalPosition(0);
}
@@ -250,9 +247,7 @@
Action.Direction.UP,
containerType);
}
- mLauncher.showAppsView(true, /* animated */
- false /* updatePredictedApps */,
- false /* focusSearchBar */);
+ mLauncher.showAppsView(true, /* animated */ false /* updatePredictedApps */);
}
}
}
@@ -282,15 +277,21 @@
}
private void updateLightStatusBar(float shift) {
- // Do not modify status bar in dark theme or on landscape as all apps is not full bleed.
- if (mIsDarkTheme || mIsWorkspaceDarkText || (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS
- && mLauncher.getDeviceProfile().isVerticalBarLayout())) {
+ // Do not modify status bar on landscape as all apps is not full bleed.
+ if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS
+ && mLauncher.getDeviceProfile().isVerticalBarLayout()) {
return;
}
- // Use a light status bar (dark icons) if all apps is behind at least half of the status
- // bar. If the status bar is already light due to wallpaper extraction, keep it that way.
- boolean forceLight = shift <= mStatusBarHeight / 2;
- mLauncher.activateLightSystemBars(forceLight, true /* statusBar */, true /* navBar */);
+
+ // Use a light system UI (dark icons) if all apps is behind at least half of the status bar.
+ boolean forceChange = shift <= mStatusBarHeight / 2;
+ if (forceChange) {
+ mLauncher.getSystemUiController().updateUiState(
+ SystemUiController.UI_STATE_ALL_APPS, !mIsDarkTheme);
+ } else {
+ mLauncher.getSystemUiController().updateUiState(
+ SystemUiController.UI_STATE_ALL_APPS, 0);
+ }
}
private void updateAllAppsBg(float progress) {
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index b84c627..608e898 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -138,13 +138,6 @@
return item;
}
- public static AdapterItem asSearchDivider(int pos) {
- AdapterItem item = new AdapterItem();
- item.viewType = AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER;
- item.position = pos;
- return item;
- }
-
public static AdapterItem asMarketDivider(int pos) {
AdapterItem item = new AdapterItem();
item.viewType = AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET_DIVIDER;
@@ -195,8 +188,6 @@
private int mNumPredictedAppsPerRow;
private int mNumAppRowsInAdapter;
- private boolean mHasSearchDivider = true;
-
public AlphabeticalAppsList(Context context) {
mLauncher = Launcher.getLauncher(context);
mIndexer = new AlphabeticIndexCompat(context);
@@ -352,10 +343,6 @@
onAppsUpdated();
}
- public void disableSearchDivider() {
- mHasSearchDivider = false;
- }
-
/**
* Updates internals when the set of apps are updated.
*/
@@ -442,11 +429,6 @@
}
}
- if (mHasSearchDivider) {
- // Add the search divider
- mAdapterItems.add(AdapterItem.asSearchDivider(position++));
- }
-
// Process the predicted app components
mPredictedApps.clear();
if (mPredictedAppComponents != null && !mPredictedAppComponents.isEmpty() && !hasFilter()) {
@@ -621,6 +603,10 @@
return result;
}
+ public AppInfo findApp(ComponentKey key) {
+ return mComponentToAppMap.get(key);
+ }
+
/**
* Returns the cached section name for the given title, recomputing and updating the cache if
* the title has no cached section name.
diff --git a/src/com/android/launcher3/allapps/LandscapeFastScroller.java b/src/com/android/launcher3/allapps/LandscapeFastScroller.java
new file mode 100644
index 0000000..cdde657
--- /dev/null
+++ b/src/com/android/launcher3/allapps/LandscapeFastScroller.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.allapps;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+import com.android.launcher3.views.RecyclerViewFastScroller;
+
+/**
+ * Extension of {@link RecyclerViewFastScroller} to be used in landscape layout.
+ */
+public class LandscapeFastScroller extends RecyclerViewFastScroller {
+
+ public LandscapeFastScroller(Context context) {
+ super(context);
+ }
+
+ public LandscapeFastScroller(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LandscapeFastScroller(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public boolean handleTouchEvent(MotionEvent ev) {
+ // We handle our own touch event, no need to handle recycler view touch delegates.
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ event.offsetLocation(0, -mRv.getPaddingTop());
+ if (super.handleTouchEvent(event)) {
+ getParent().requestDisallowInterceptTouchEvent(true);
+ }
+ event.offsetLocation(0, mRv.getPaddingTop());
+ return true;
+ }
+
+ @Override
+ public boolean shouldBlockIntercept(int x, int y) {
+ // If the user touched the scroll bar area, block swipe
+ return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
+ }
+}
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
index 0d013c7..c0d7850 100644
--- a/src/com/android/launcher3/allapps/SearchUiManager.java
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -44,18 +44,6 @@
*/
void preDispatchKeyEvent(KeyEvent keyEvent);
- /**
- * Returns true if the IME should be brought back.
- * TODO: Remove when removing support for opening all-apps in search mode.
- */
- boolean shouldRestoreImeState();
-
- /**
- * Starts the search UI
- * TODO: Remove when removing support for opening all-apps in search mode.
- */
- void startAppsSearch();
-
void addOnScrollRangeChangeListener(OnScrollRangeChangeListener listener);
/**
diff --git a/src/com/android/launcher3/allapps/VerticalPullDetector.java b/src/com/android/launcher3/allapps/VerticalPullDetector.java
index 7800c01..13c4f63 100644
--- a/src/com/android/launcher3/allapps/VerticalPullDetector.java
+++ b/src/com/android/launcher3/allapps/VerticalPullDetector.java
@@ -17,7 +17,7 @@
private static final boolean DBG = false;
private static final String TAG = "VerticalPullDetector";
- private float mTouchSlop;
+ private final float mTouchSlop;
private int mScrollConditions;
public static final int DIRECTION_UP = 1 << 0;
@@ -47,8 +47,6 @@
SETTLING // onDragEnd
}
- ;
-
//------------------- ScrollState transition diagram -----------------------------------
//
// IDLE -> (mDisplacement > mTouchSlop) -> DRAGGING
@@ -110,7 +108,7 @@
private boolean mIgnoreSlopWhenSettling;
/* Client of this gesture detector can register a callback. */
- Listener mListener;
+ private Listener mListener;
public void setListener(Listener l) {
mListener = l;
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index cb3b066..5cb12d5 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -23,13 +23,11 @@
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
import android.text.method.TextKeyListener;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.widget.FrameLayout;
-
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Launcher;
@@ -43,7 +41,6 @@
import com.android.launcher3.discovery.AppDiscoveryUpdateState;
import com.android.launcher3.graphics.TintedDrawableSpan;
import com.android.launcher3.util.ComponentKey;
-
import java.util.ArrayList;
/**
@@ -57,12 +54,13 @@
private final int mSearchBoxHeight;
private final AllAppsSearchBarController mSearchBarController;
private final SpannableStringBuilder mSearchQueryBuilder;
- private final HeaderElevationController mElevationController;
private ExtendedEditText mSearchInput;
private AlphabeticalAppsList mApps;
private AllAppsRecyclerView mAppsRecyclerView;
private AllAppsGridAdapter mAdapter;
+ private View mDivider;
+ private HeaderElevationController mElevationController;
public AppsSearchContainerLayout(Context context) {
this(context, null);
@@ -80,7 +78,6 @@
mSearchBoxHeight = getResources()
.getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height);
mSearchBarController = new AllAppsSearchBarController();
- mElevationController = new HeaderElevationController(this);
mSearchQueryBuilder = new SpannableStringBuilder();
Selection.setSelection(mSearchQueryBuilder, 0);
@@ -90,6 +87,8 @@
protected void onFinishInflate() {
super.onFinishInflate();
mSearchInput = findViewById(R.id.search_box_input);
+ mDivider = findViewById(R.id.search_divider);
+ mElevationController = new HeaderElevationController(mDivider);
// Update the hint to contain the icon.
// Prefix the original hint with two spaces. The first space gets replaced by the icon
@@ -99,6 +98,12 @@
spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
mSearchInput.setHint(spanned);
+
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ if (!dp.isVerticalBarLayout()) {
+ LayoutParams lp = (LayoutParams) mDivider.getLayoutParams();
+ lp.leftMargin = lp.rightMargin = dp.edgeMarginPx;
+ }
}
@Override
@@ -153,18 +158,6 @@
}
@Override
- public boolean shouldRestoreImeState() {
- return !TextUtils.isEmpty(mSearchInput.getText());
- }
-
- @Override
- public void startAppsSearch() {
- if (mApps != null) {
- mSearchBarController.focusSearchField();
- }
- }
-
- @Override
public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
if (apps != null) {
mApps.setOrderedFilter(apps);
diff --git a/src/com/android/launcher3/allapps/search/HeaderElevationController.java b/src/com/android/launcher3/allapps/search/HeaderElevationController.java
index ab4e88f..7cd32b2 100644
--- a/src/com/android/launcher3/allapps/search/HeaderElevationController.java
+++ b/src/com/android/launcher3/allapps/search/HeaderElevationController.java
@@ -4,11 +4,11 @@
import android.graphics.Outline;
import android.support.v7.widget.RecyclerView;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
/**
* Helper class for controlling the header elevation in response to RecyclerView scroll.
@@ -16,6 +16,7 @@
public class HeaderElevationController extends RecyclerView.OnScrollListener {
private final View mHeader;
+ private final View mHeaderChild;
private final float mMaxElevation;
private final float mScrollToElevation;
@@ -28,23 +29,27 @@
mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation);
// We need to provide a custom outline so the shadow only appears on the bottom edge.
- // The top, left and right edges are all extended out, and the shadow is clipped
- // by the parent.
+ // The top, left and right edges are all extended out to match parent's edge, so that
+ // the shadow is clipped by the parent.
final ViewOutlineProvider vop = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- final View parent = (View) mHeader.getParent();
+ // Set the left and top to be at the parents edge. Since the coordinates are
+ // relative to this view,
+ // (x = -view.getLeft()) for this view => (x = 0) for parent
+ final int left = -view.getLeft();
+ final int top = -view.getTop();
- final int left = parent.getLeft(); // Use the parent to account for offsets
- final int top = view.getTop();
- final int right = left + view.getWidth();
- final int bottom = view.getBottom();
-
- final int offset = Utilities.pxFromDp(mMaxElevation, res.getDisplayMetrics());
+ // Since the view is centered align, the spacing on left and right are same.
+ // Add same spacing on the right to reach parent's edge.
+ final int right = view.getWidth() - left;
+ final int bottom = view.getHeight();
+ final int offset = (int) mMaxElevation;
outline.setRect(left - offset, top - offset, right + offset, bottom);
}
};
mHeader.setOutlineProvider(vop);
+ mHeaderChild = ((ViewGroup) mHeader).getChildAt(0);
}
public void reset() {
@@ -63,6 +68,13 @@
float newElevation = mMaxElevation * elevationPct;
if (Float.compare(mHeader.getElevation(), newElevation) != 0) {
mHeader.setElevation(newElevation);
+
+ // To simulate a scrolling effect for the header, we translate the header down, and
+ // its content up by the same amount, so that it gets clipped by the parent, making it
+ // look like the content was scrolled out of the view.
+ int shift = Math.min(mHeader.getHeight(), scrollY);
+ mHeader.setTranslationY(-shift);
+ mHeaderChild.setTranslationY(shift);
}
}
diff --git a/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
index d01b26c..7c5fa1c 100644
--- a/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
+++ b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
@@ -56,7 +56,7 @@
@Override
public boolean shouldRemoveElevationDuringAnimation() {
- return false;
+ return true;
}
@Override
diff --git a/src/com/android/launcher3/badge/BadgeRenderer.java b/src/com/android/launcher3/badge/BadgeRenderer.java
index ba1977a..c2cc215 100644
--- a/src/com/android/launcher3/badge/BadgeRenderer.java
+++ b/src/com/android/launcher3/badge/BadgeRenderer.java
@@ -107,7 +107,8 @@
// Lazily load the background with shadow.
Bitmap backgroundWithShadow = mBackgroundsWithShadow.get(numChars);
if (backgroundWithShadow == null) {
- backgroundWithShadow = ShadowGenerator.createPillWithShadow(Color.WHITE, width, mSize);
+ backgroundWithShadow = new ShadowGenerator.Builder(Color.WHITE)
+ .setupBlurForSize(mSize).createPill(width, mSize);
mBackgroundsWithShadow.put(numChars, backgroundWithShadow);
}
canvas.save(Canvas.MATRIX_SAVE_FLAG);
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index 647c315..cc3e5a7 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -29,23 +29,22 @@
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-
+import android.util.ArrayMap;
import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVL;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.util.PackageUserKey;
-
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
public class LauncherAppsCompatVL extends LauncherAppsCompat {
protected final LauncherApps mLauncherApps;
protected final Context mContext;
- private Map<OnAppsChangedCallbackCompat, WrappedCallback> mCallbacks = new HashMap<>();
+ private final ArrayMap<OnAppsChangedCallbackCompat, WrappedCallback> mCallbacks =
+ new ArrayMap<>();
LauncherAppsCompatVL(Context context) {
mContext = context;
@@ -131,43 +130,52 @@
}
private static class WrappedCallback extends LauncherApps.Callback {
- private LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;
+ private final LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;
public WrappedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
mCallback = callback;
}
+ @Override
public void onPackageRemoved(String packageName, UserHandle user) {
mCallback.onPackageRemoved(packageName, user);
}
+ @Override
public void onPackageAdded(String packageName, UserHandle user) {
mCallback.onPackageAdded(packageName, user);
}
+ @Override
public void onPackageChanged(String packageName, UserHandle user) {
mCallback.onPackageChanged(packageName, user);
}
+ @Override
public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
mCallback.onPackagesAvailable(packageNames, user, replacing);
}
+ @Override
public void onPackagesUnavailable(String[] packageNames, UserHandle user,
boolean replacing) {
mCallback.onPackagesUnavailable(packageNames, user, replacing);
}
+ @Override
public void onPackagesSuspended(String[] packageNames, UserHandle user) {
mCallback.onPackagesSuspended(packageNames, user);
}
+ @Override
public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
mCallback.onPackagesUnsuspended(packageNames, user);
}
- public void onShortcutsChanged(String packageName, List<ShortcutInfo> shortcuts,
- UserHandle user) {
+ @Override
+ public void onShortcutsChanged(@NonNull String packageName,
+ @NonNull List<ShortcutInfo> shortcuts,
+ @NonNull UserHandle user) {
List<ShortcutInfoCompat> shortcutInfoCompats = new ArrayList<>(shortcuts.size());
for (ShortcutInfo shortcutInfo : shortcuts) {
shortcutInfoCompats.add(new ShortcutInfoCompat(shortcutInfo));
diff --git a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
index 6bdc627..31c0087 100644
--- a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
+++ b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
@@ -125,7 +125,7 @@
}
@TargetApi(26)
- static class ShortcutConfigActivityInfoVO extends ShortcutConfigActivityInfo {
+ public static class ShortcutConfigActivityInfoVO extends ShortcutConfigActivityInfo {
private final LauncherActivityInfo mInfo;
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index c7f88f6..bb42573 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -21,13 +21,11 @@
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.os.UserManager;
-
+import android.util.ArrayMap;
import com.android.launcher3.util.LongArrayMap;
import com.android.launcher3.util.ManagedProfileHeuristic;
-
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
public class UserManagerCompatVL extends UserManagerCompat {
@@ -40,7 +38,7 @@
protected LongArrayMap<UserHandle> mUsers;
// Create a separate reverse map as LongArrayMap.indexOfValue checks if objects are same
// and not {@link Object#equals}
- protected HashMap<UserHandle, Long> mUserToSerialMap;
+ protected ArrayMap<UserHandle, Long> mUserToSerialMap;
UserManagerCompatVL(Context context) {
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
@@ -88,7 +86,7 @@
public void enableAndResetCache() {
synchronized (this) {
mUsers = new LongArrayMap<>();
- mUserToSerialMap = new HashMap<>();
+ mUserToSerialMap = new ArrayMap<>();
List<UserHandle> users = mUserManager.getUserProfiles();
if (users != null) {
for (UserHandle user : users) {
diff --git a/src/com/android/launcher3/compat/WallpaperColorsCompat.java b/src/com/android/launcher3/compat/WallpaperColorsCompat.java
index fd08f94..58d2a80 100644
--- a/src/com/android/launcher3/compat/WallpaperColorsCompat.java
+++ b/src/com/android/launcher3/compat/WallpaperColorsCompat.java
@@ -15,29 +15,40 @@
*/
package com.android.launcher3.compat;
-import android.util.SparseIntArray;
-
/**
* A compatibility layer around platform implementation of WallpaperColors
*/
public class WallpaperColorsCompat {
- private final SparseIntArray mColors;
- private final boolean mSupportsDarkText;
+ public static final int HINT_SUPPORTS_DARK_TEXT = 0x1;
- public WallpaperColorsCompat(SparseIntArray colors, boolean supportsDarkText) {
- mColors = colors;
- mSupportsDarkText = supportsDarkText;
+ private final int mPrimaryColor;
+ private final int mSecondaryColor;
+ private final int mTertiaryColor;
+ private final int mColorHints;
+
+ public WallpaperColorsCompat(int primaryColor, int secondaryColor, int tertiaryColor,
+ int colorHints) {
+ mPrimaryColor = primaryColor;
+ mSecondaryColor = secondaryColor;
+ mTertiaryColor = tertiaryColor;
+ mColorHints = colorHints;
}
- /**
- * A map of color code to their occurrences. The bigger the int, the more relevant the color.
- */
- public SparseIntArray getColors() {
- return mColors;
+ public int getPrimaryColor() {
+ return mPrimaryColor;
}
- public boolean supportsDarkText() {
- return mSupportsDarkText;
+ public int getSecondaryColor() {
+ return mSecondaryColor;
}
+
+ public int getTertiaryColor() {
+ return mTertiaryColor;
+ }
+
+ public int getColorHints() {
+ return mColorHints;
+ }
+
}
diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java b/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java
index 8bdcedb..8e572ee 100644
--- a/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java
@@ -15,10 +15,6 @@
*/
package com.android.launcher3.compat;
-import static android.app.WallpaperManager.FLAG_SYSTEM;
-
-import static com.android.launcher3.Utilities.getDevicePrefs;
-
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.app.job.JobInfo;
@@ -45,12 +41,17 @@
import android.support.v7.graphics.Palette;
import android.util.Log;
import android.util.Pair;
-import android.util.SparseIntArray;
import com.android.launcher3.Utilities;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import static android.app.WallpaperManager.FLAG_SYSTEM;
+import static com.android.launcher3.Utilities.getDevicePrefs;
public class WallpaperManagerCompatVL extends WallpaperManagerCompat {
@@ -154,11 +155,12 @@
return Pair.create(wallpaperId, null);
}
- SparseIntArray colorsToOccurrences = new SparseIntArray((parts.length - 2) / 2);
- for (int i = 2; i < parts.length; i += 2) {
- colorsToOccurrences.put(Integer.parseInt(parts[i]), Integer.parseInt(parts[i + 1]));
- }
- return Pair.create(wallpaperId, new WallpaperColorsCompat(colorsToOccurrences, false));
+ int primary = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
+ int secondary = parts.length > 3 ? Integer.parseInt(parts[3]) : 0;
+ int tertiary = parts.length > 4 ? Integer.parseInt(parts[4]) : 0;
+
+ return Pair.create(wallpaperId, new WallpaperColorsCompat(primary, secondary, tertiary,
+ 0 /* hints */));
}
/**
@@ -262,12 +264,22 @@
bitmap.recycle();
StringBuilder builder = new StringBuilder(value);
+ List<Pair<Integer,Integer>> colorsToOccurrences = new ArrayList<>();
for (Palette.Swatch swatch : palette.getSwatches()) {
- builder.append(',')
- .append(swatch.getRgb())
- .append(',')
- .append(swatch.getPopulation());
+ colorsToOccurrences.add(new Pair(swatch.getRgb(), swatch.getPopulation()));
}
+
+ Collections.sort(colorsToOccurrences, new Comparator<Pair<Integer, Integer>>() {
+ @Override
+ public int compare(Pair<Integer, Integer> a, Pair<Integer, Integer> b) {
+ return b.second - a.second;
+ }
+ });
+
+ for (int i=0; i < Math.min(3, colorsToOccurrences.size()); i++) {
+ builder.append(',').append(colorsToOccurrences.get(i).first);
+ }
+
value = builder.toString();
}
diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java b/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java
index c74ccc0..6233fab 100644
--- a/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java
+++ b/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java
@@ -22,13 +22,10 @@
import android.os.Build;
import android.support.annotation.Nullable;
import android.util.Log;
-import android.util.Pair;
-import android.util.SparseIntArray;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import java.util.List;
@TargetApi(Build.VERSION_CODES.O)
public class WallpaperManagerCompatVOMR1 extends WallpaperManagerCompat {
@@ -41,8 +38,10 @@
private final Method mAddOCLMethod;
private final Method mWCGetMethod;
- private final Method mWCGetColorsMethod;
- private final Method mWCSupportsDarkTextMethod;
+ private final Method mWCGetPrimaryColorMethod;
+ private final Method mWCGetSecondaryColorMethod;
+ private final Method mWCGetTertiaryColorMethod;
+ private final Method mWCColorHintsMethod;
WallpaperManagerCompatVOMR1(Context context) throws Exception {
mWm = context.getSystemService(WallpaperManager.class);
@@ -53,8 +52,10 @@
mWCGetMethod = WallpaperManager.class.getDeclaredMethod("getWallpaperColors", int.class);
Class wallpaperColorsClass = mWCGetMethod.getReturnType();
- mWCGetColorsMethod = wallpaperColorsClass.getDeclaredMethod("getColors");
- mWCSupportsDarkTextMethod = wallpaperColorsClass.getDeclaredMethod("supportsDarkText");
+ mWCGetPrimaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getPrimaryColor");
+ mWCGetSecondaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getSecondaryColor");
+ mWCGetTertiaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getTertiaryColor");
+ mWCColorHintsMethod = wallpaperColorsClass.getDeclaredMethod("getColorHints");
}
@Nullable
@@ -98,12 +99,13 @@
if (colors == null) {
return null;
}
- List<Pair<Color, Integer>> list = (List) mWCGetColorsMethod.invoke(colors);
- boolean supportsDarkText = (Boolean) mWCSupportsDarkTextMethod.invoke(colors);
- SparseIntArray colorMap = new SparseIntArray(list.size());
- for (Pair<Color, Integer> color : list) {
- colorMap.put(color.first.toArgb(), color.second);
- }
- return new WallpaperColorsCompat(colorMap, supportsDarkText);
+ Color primary = (Color) mWCGetPrimaryColorMethod.invoke(colors);
+ Color secondary = (Color) mWCGetSecondaryColorMethod.invoke(colors);
+ Color tertiary = (Color) mWCGetTertiaryColorMethod.invoke(colors);
+ int primaryVal = primary != null ? primary.toArgb() : 0;
+ int secondaryVal = secondary != null ? secondary.toArgb() : 0;
+ int tertiaryVal = tertiary != null ? tertiary.toArgb() : 0;
+ int colorHints = (Integer) mWCColorHintsMethod.invoke(colors);
+ return new WallpaperColorsCompat(primaryVal, secondaryVal, tertiaryVal, colorHints);
}
}
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 29789c8..01893bd 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -84,6 +84,8 @@
private int mPendingBindWidgetId;
private Bundle mWidgetOptions;
+ private boolean mFinishOnPause = false;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -163,6 +165,7 @@
startActivity(homeIntent,
ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out).toBundle());
+ mFinishOnPause = true;
// Start a system drag and drop. We use a transparent bitmap as preview for system drag
// as the preview is handled internally by launcher.
@@ -182,6 +185,14 @@
return false;
}
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if (mFinishOnPause) {
+ finish();
+ }
+ }
+
private void setupShortcut() {
PinShortcutRequestActivityInfo shortcutInfo =
new PinShortcutRequestActivityInfo(mRequest, this);
diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
new file mode 100644
index 0000000..d0f2629
--- /dev/null
+++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.dragndrop;
+
+import android.content.ClipDescription;
+import android.content.Intent;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Parcel;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.DragEvent;
+import android.view.View;
+
+import com.android.launcher3.DeleteDropTarget;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.folder.Folder;
+import com.android.launcher3.widget.PendingItemDragHelper;
+
+import java.util.UUID;
+
+/**
+ * {@link DragSource} for handling drop from a different window.
+ */
+public abstract class BaseItemDragListener implements
+ View.OnDragListener, DragSource, DragOptions.PreDragCondition {
+
+ private static final String TAG = "BaseItemDragListener";
+
+ private static final String MIME_TYPE_PREFIX = "com.android.launcher3.drag_and_drop/";
+ public static final String EXTRA_PIN_ITEM_DRAG_LISTENER = "pin_item_drag_listener";
+
+ // Position of preview relative to the touch location
+ private final Rect mPreviewRect;
+
+ private final int mPreviewBitmapWidth;
+ private final int mPreviewViewWidth;
+
+ // Randomly generated id used to verify the drag event.
+ private final String mId;
+
+ protected Launcher mLauncher;
+ private DragController mDragController;
+ private long mDragStartTime;
+
+ public BaseItemDragListener(Rect previewRect, int previewBitmapWidth, int previewViewWidth) {
+ mPreviewRect = previewRect;
+ mPreviewBitmapWidth = previewBitmapWidth;
+ mPreviewViewWidth = previewViewWidth;
+ mId = UUID.randomUUID().toString();
+ }
+
+ protected BaseItemDragListener(Parcel parcel) {
+ mPreviewRect = Rect.CREATOR.createFromParcel(parcel);
+ mPreviewBitmapWidth = parcel.readInt();
+ mPreviewViewWidth = parcel.readInt();
+ mId = parcel.readString();
+ }
+
+ protected void writeToParcel(Parcel parcel, int i) {
+ mPreviewRect.writeToParcel(parcel, i);
+ parcel.writeInt(mPreviewBitmapWidth);
+ parcel.writeInt(mPreviewViewWidth);
+ parcel.writeString(mId);
+ }
+
+ public String getMimeType() {
+ return MIME_TYPE_PREFIX + mId;
+ }
+
+ public void setLauncher(Launcher launcher) {
+ mLauncher = launcher;
+ mDragController = launcher.getDragController();
+ }
+
+ @Override
+ public boolean onDrag(View view, DragEvent event) {
+ if (mLauncher == null || mDragController == null) {
+ postCleanup();
+ return false;
+ }
+ if (event.getAction() == DragEvent.ACTION_DRAG_STARTED) {
+ if (onDragStart(event)) {
+ return true;
+ } else {
+ postCleanup();
+ return false;
+ }
+ }
+ return mDragController.onDragEvent(mDragStartTime, event);
+ }
+
+ protected boolean onDragStart(DragEvent event) {
+ ClipDescription desc = event.getClipDescription();
+ if (desc == null || !desc.hasMimeType(getMimeType())) {
+ Log.e(TAG, "Someone started a dragAndDrop before us.");
+ return false;
+ }
+
+ Point downPos = new Point((int) event.getX(), (int) event.getY());
+ DragOptions options = new DragOptions();
+ options.systemDndStartPoint = downPos;
+ options.preDragCondition = this;
+
+ // We use drag event position as the screenPos for the preview image. Since mPreviewRect
+ // already includes the view position relative to the drag event on the source window,
+ // and the absolute position (position relative to the screen) of drag event is same
+ // across windows, using drag position here give a good estimate for relative position
+ // to source window.
+ createDragHelper().startDrag(new Rect(mPreviewRect),
+ mPreviewBitmapWidth, mPreviewViewWidth, downPos, this, options);
+ mDragStartTime = SystemClock.uptimeMillis();
+ return true;
+ }
+
+ protected abstract PendingItemDragHelper createDragHelper();
+
+ @Override
+ public boolean shouldStartDrag(double distanceDragged) {
+ // Stay in pre-drag mode, if workspace is locked.
+ return !mLauncher.isWorkspaceLocked();
+ }
+
+ @Override
+ public void onPreDragStart(DropTarget.DragObject dragObject) {
+ // The predrag starts when the workspace is not yet loaded. In some cases we set
+ // the dragLayer alpha to 0 to have a nice fade-in animation. But that will prevent the
+ // dragView from being visible. Instead just skip the fade-in animation here.
+ mLauncher.getDragLayer().setAlpha(1);
+
+ dragObject.dragView.setColor(
+ mLauncher.getResources().getColor(R.color.delete_target_hover_tint));
+ }
+
+ @Override
+ public void onPreDragEnd(DropTarget.DragObject dragObject, boolean dragStarted) {
+ if (dragStarted) {
+ dragObject.dragView.setColor(0);
+ }
+ }
+
+ @Override
+ public boolean supportsAppInfoDropTarget() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsDeleteDropTarget() {
+ return false;
+ }
+
+ @Override
+ public float getIntrinsicIconScaleFactor() {
+ return 1f;
+ }
+
+ @Override
+ public void onDropCompleted(View target, DropTarget.DragObject d, boolean isFlingToDelete,
+ boolean success) {
+ if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() &&
+ !(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
+ // Exit spring loaded mode if we have not successfully dropped or have not handled the
+ // drop in Workspace
+ mLauncher.exitSpringLoadedDragModeDelayed(true,
+ Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
+ }
+
+ if (!success) {
+ d.deferDragViewCleanupPostAnimation = false;
+ }
+ postCleanup();
+ }
+
+ private void postCleanup() {
+ if (mLauncher != null) {
+ // Remove any drag params from the launcher intent since the drag operation is complete.
+ Intent newIntent = new Intent(mLauncher.getIntent());
+ newIntent.removeExtra(EXTRA_PIN_ITEM_DRAG_LISTENER);
+ mLauncher.setIntent(newIntent);
+ }
+
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ removeListener();
+ }
+ });
+ }
+
+ public void removeListener() {
+ if (mLauncher != null) {
+ mLauncher.getDragLayer().setOnDragListener(null);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index 7410ae6..b852714 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -165,7 +165,7 @@
? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f;
final DragView dragView = mDragObject.dragView = new DragView(mLauncher, b, registrationX,
registrationY, initialDragViewScale, scaleDps);
-
+ dragView.setItemInfo(dragInfo);
mDragObject.dragComplete = false;
if (mOptions.isAccessibleDrag) {
// For an accessible drag, we assume the view is being dragged from the center.
@@ -210,13 +210,13 @@
}
private void callOnDragStart() {
- for (DragListener listener : new ArrayList<>(mListeners)) {
- listener.onDragStart(mDragObject, mOptions);
- }
if (mOptions.preDragCondition != null) {
mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/);
}
mIsInPreDrag = false;
+ for (DragListener listener : new ArrayList<>(mListeners)) {
+ listener.onDragStart(mDragObject, mOptions);
+ }
}
/**
diff --git a/src/com/android/launcher3/dragndrop/DragDriver.java b/src/com/android/launcher3/dragndrop/DragDriver.java
index 65c0f29..d8a3024 100644
--- a/src/com/android/launcher3/dragndrop/DragDriver.java
+++ b/src/com/android/launcher3/dragndrop/DragDriver.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.view.DragEvent;
import android.view.MotionEvent;
-
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.Utilities;
@@ -97,16 +96,11 @@
*/
class SystemDragDriver extends DragDriver {
- private final DragObject mDragObject;
- private final Context mContext;
-
float mLastX = 0;
float mLastY = 0;
- public SystemDragDriver(DragController dragController, Context context, DragObject dragObject) {
+ SystemDragDriver(DragController dragController, Context context, DragObject dragObject) {
super(dragController);
- mDragObject = dragObject;
- mContext = context;
}
@Override
@@ -162,10 +156,10 @@
* Class for driving an internal (i.e. not using framework) drag/drop operation.
*/
class InternalDragDriver extends DragDriver {
- public InternalDragDriver(DragController dragController) {
+ InternalDragDriver(DragController dragController) {
super(dragController);
}
@Override
public boolean onDragEvent (DragEvent event) { return false; }
-};
+}
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 7806c98..022b3b8 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -16,31 +16,67 @@
package com.android.launcher3.dragndrop;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.FloatArrayEvaluator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.pm.LauncherActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.animation.DynamicAnimation;
+import android.support.animation.SpringAnimation;
+import android.support.animation.SpringForce;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import com.android.launcher3.FastBitmapDrawable;
+import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherModel;
+import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.ShortcutConfigActivityInfo;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.graphics.IconNormalizer;
+import com.android.launcher3.graphics.LauncherIcons;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
+import com.android.launcher3.shortcuts.ShortcutInfoCompat;
+import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.PendingAddShortcutInfo;
import java.util.Arrays;
+import java.util.List;
-public class DragView extends View {
+public class DragView extends FrameLayout {
public static final int COLOR_CHANGE_DURATION = 120;
public static final int VIEW_ZOOM_DURATION = 150;
@@ -57,6 +93,7 @@
private Point mDragVisualizeOffset = null;
private Rect mDragRegion = null;
+ private final Launcher mLauncher;
private final DragLayer mDragLayer;
@Thunk final DragController mDragController;
private boolean mHasDrawn = false;
@@ -76,6 +113,18 @@
private int mAnimatedShiftX;
private int mAnimatedShiftY;
+ // Below variable only needed IF FeatureFlags.LAUNCHER3_SPRING_ICONS is {@code true}
+ private SpringAnimation mSpringX, mSpringY;
+ private ImageView mFgImageView, mBgImageView;
+ private Path mScaledMaskPath;
+ private Drawable mBadge;
+
+ // Following three values are fine tuned with motion ux designer
+ private final static int STIFFNESS = 4000;
+ private final static float DAMPENING_RATIO = 1f;
+ private final static int PARALLAX_MAX_IN_DP = 8;
+ private final int mDelta;
+
/**
* Construct the drag view.
* <p>
@@ -89,6 +138,7 @@
public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY,
final float initialScale, final float finalScaleDps) {
super(launcher);
+ mLauncher = launcher;
mDragLayer = launcher.getDragLayer();
mDragController = launcher.getDragController();
@@ -142,8 +192,210 @@
mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
mBlurSizeOutline = getResources().getDimensionPixelSize(R.dimen.blur_size_medium_outline);
-
setElevation(getResources().getDimension(R.dimen.drag_elevation));
+ setWillNotDraw(false);
+ mDelta = (int)(getResources().getDisplayMetrics().density * PARALLAX_MAX_IN_DP);
+ }
+
+ /**
+ * Initialize {@code #mIconDrawable} only if the icon type is app icon (not shortcut or folder).
+ */
+ @TargetApi(Build.VERSION_CODES.O)
+ public void setItemInfo(final ItemInfo info) {
+ if (!(FeatureFlags.LAUNCHER3_SPRING_ICONS && Utilities.isAtLeastO())) {
+ return;
+ }
+ if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
+ info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+ return;
+ }
+ // Load the adaptive icon on a background thread and add the view in ui thread.
+ final Looper workerLooper = LauncherModel.getWorkerLooper();
+ new Handler(workerLooper).postAtFrontOfQueue(new Runnable() {
+ @Override
+ public void run() {
+ LauncherAppState appState = LauncherAppState.getInstance(mLauncher);
+ Object[] outObj = new Object[1];
+ Drawable dr = getFullDrawable(info, appState, outObj);
+
+ if (dr instanceof AdaptiveIconDrawable) {
+ int w = mBitmap.getWidth();
+ int h = mBitmap.getHeight();
+ AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr;
+ adaptiveIcon.setBounds(0, 0, w, h);
+ float blurSizeOutline = mLauncher.getResources()
+ .getDimension(R.dimen.blur_size_medium_outline);
+ float normalizationScale = IconNormalizer.getInstance(mLauncher)
+ .getScale(adaptiveIcon, null, null, null) * ((w - blurSizeOutline) / w);
+
+ final Path mask = getMaskPath(adaptiveIcon, normalizationScale);
+ mFgImageView = setupImageView(adaptiveIcon.getForeground(), normalizationScale);
+ mBgImageView = setupImageView(adaptiveIcon.getBackground(), normalizationScale);
+ mSpringX = setupSpringAnimation(-w/4, w/4, DynamicAnimation.TRANSLATION_X);
+ mSpringY = setupSpringAnimation(-h/4, h/4, DynamicAnimation.TRANSLATION_Y);
+
+ mBadge = getBadge(info, appState, outObj[0]);
+ int blurMargin = (int) blurSizeOutline / 2;
+ mBadge.setBounds(blurMargin, blurMargin, w - blurMargin, h - blurMargin);
+
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ // Assign the variable on the UI thread to avoid race conditions.
+ mScaledMaskPath = mask;
+ addView(mBgImageView);
+ addView(mFgImageView);
+ setWillNotDraw(true);
+
+ if (info.isDisabled()) {
+ FastBitmapDrawable d = new FastBitmapDrawable(null);
+ d.setIsDisabled(true);
+ ColorFilter cf = d.getColorFilter();
+ mBgImageView.setColorFilter(cf);
+ mFgImageView.setColorFilter(cf);
+ mBadge.setColorFilter(cf);
+ }
+ }
+ });
+ }
+ }});
+ }
+
+ /**
+ * Returns the full drawable for {@param info}.
+ * @param outObj this is set to the internal data associated with {@param info},
+ * eg {@link LauncherActivityInfo} or {@link ShortcutInfoCompat}.
+ */
+ private Drawable getFullDrawable(ItemInfo info, LauncherAppState appState, Object[] outObj) {
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+ LauncherActivityInfo activityInfo = LauncherAppsCompat.getInstance(mLauncher)
+ .resolveActivity(info.getIntent(), info.user);
+ outObj[0] = activityInfo;
+ return (activityInfo != null) ? appState.getIconCache()
+ .getFullResIcon(activityInfo, false) : null;
+ } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+ if (info instanceof PendingAddShortcutInfo) {
+ ShortcutConfigActivityInfo activityInfo =
+ ((PendingAddShortcutInfo) info).activityInfo;
+ outObj[0] = activityInfo;
+ return activityInfo.getFullResIcon(appState.getIconCache());
+ }
+ ShortcutKey key = ShortcutKey.fromItemInfo(info);
+ DeepShortcutManager sm = DeepShortcutManager.getInstance(mLauncher);
+ List<ShortcutInfoCompat> si = sm.queryForFullDetails(
+ key.componentName.getPackageName(), Arrays.asList(key.getId()), key.user);
+ if (si.isEmpty()) {
+ return null;
+ } else {
+ outObj[0] = si.get(0);
+ return sm.getShortcutIconDrawable(si.get(0),
+ appState.getInvariantDeviceProfile().fillResIconDpi);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * For apps icons and shortcut icons that have badges, this method creates a drawable that can
+ * later on be rendered on top of the layers for the badges. For app icons, work profile badges
+ * can only be applied. For deep shortcuts, when dragged from the pop up container, there's no
+ * badge. When dragged from workspace or folder, it may contain app AND/OR work profile badge
+ **/
+
+ @TargetApi(Build.VERSION_CODES.O)
+ private Drawable getBadge(ItemInfo info, LauncherAppState appState, Object obj) {
+ int iconSize = appState.getInvariantDeviceProfile().iconBitmapSize;
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+ if (info.id == ItemInfo.NO_ID || !(obj instanceof ShortcutInfoCompat)) {
+ // The item is not yet added on home screen.
+ return new FixedSizeEmptyDrawable(iconSize);
+ }
+ ShortcutInfoCompat si = (ShortcutInfoCompat) obj;
+ Bitmap badge = LauncherIcons.getShortcutInfoBadge(si, appState.getIconCache());
+
+ float badgeSize = mLauncher.getResources().getDimension(R.dimen.profile_badge_size);
+ float insetFraction = (iconSize - badgeSize) / iconSize;
+ return new InsetDrawable(new FastBitmapDrawable(badge),
+ insetFraction, insetFraction, 0, 0);
+ } else {
+ return mLauncher.getPackageManager()
+ .getUserBadgedIcon(new FixedSizeEmptyDrawable(iconSize), info.user);
+ }
+ }
+
+ private ImageView setupImageView(Drawable drawable, float normalizationScale) {
+ FrameLayout.LayoutParams params = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
+ ImageView imageViewOut = new ImageView(getContext());
+ imageViewOut.setLayoutParams(params);
+ imageViewOut.setScaleType(ImageView.ScaleType.FIT_XY);
+ imageViewOut.setScaleX(normalizationScale);
+ imageViewOut.setScaleY(normalizationScale);
+ imageViewOut.setImageDrawable(drawable);
+ return imageViewOut;
+ }
+
+ private SpringAnimation setupSpringAnimation(int minValue, int maxValue,
+ DynamicAnimation.ViewProperty property) {
+ SpringAnimation s = new SpringAnimation(mFgImageView, property, 0);
+ s.setMinValue(minValue).setMaxValue(maxValue);
+ s.setSpring(new SpringForce(0)
+ .setDampingRatio(DAMPENING_RATIO)
+ .setStiffness(STIFFNESS));
+ return s;
+ }
+
+ @TargetApi(Build.VERSION_CODES.O)
+ private Path getMaskPath(AdaptiveIconDrawable dr, float normalizationScale) {
+ Matrix m = new Matrix();
+ // Shrink very tiny bit so that the clip path is smaller than the original bitmap
+ // that has anti aliased edges and shadows.
+ float s = normalizationScale * .97f;
+ m.setScale(s, s, dr.getBounds().centerX(), dr.getBounds().centerY());
+ Path p = new Path();
+ dr.getIconMask().transform(m, p);
+ return p;
+ }
+
+ private void applySpring(int x, int y) {
+ if (mSpringX == null || mSpringY == null) {
+ return;
+ }
+ mSpringX.animateToFinalPosition(Utilities.boundToRange(x, -mDelta, mDelta));
+ mSpringY.animateToFinalPosition(Utilities.boundToRange(y, -mDelta, mDelta));
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ int w = right - left;
+ int h = bottom - top;
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).layout(-w / 4, -h / 4, w + w / 4, h + h / 4);
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int w = mBitmap.getWidth();
+ int h = mBitmap.getHeight();
+ setMeasuredDimension(w, h);
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).measure(w, h);
+ }
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ if (mScaledMaskPath != null) {
+ int cnt = canvas.save();
+ canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
+ canvas.clipPath(mScaledMaskPath);
+ super.dispatchDraw(canvas);
+ canvas.restoreToCount(cnt);
+ mBadge.draw(canvas);
+ } else {
+ super.dispatchDraw(canvas);
+ }
}
/** Sets the scale of the view over the normal workspace icon size. */
@@ -187,11 +439,6 @@
return mDragRegion;
}
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
- }
-
// Draws drag shadow for system DND.
@SuppressLint("WrongCall")
public void drawDragShadow(Canvas canvas) {
@@ -343,6 +590,9 @@
* @param touchY the y coordinate the user touched in DragLayer coordinates
*/
public void move(int touchX, int touchY) {
+ if (touchX > 0 && touchY > 0 && mLastTouchX > 0 && mLastTouchY > 0) {
+ applySpring(mLastTouchX - touchX, mLastTouchY - touchY);
+ }
mLastTouchX = touchX;
mLastTouchY = touchY;
applyTranslation();
@@ -391,4 +641,24 @@
public float getInitialScale() {
return mInitialScale;
}
+
+ private static class FixedSizeEmptyDrawable extends ColorDrawable {
+
+ private final int mSize;
+
+ public FixedSizeEmptyDrawable(int size) {
+ super(Color.TRANSPARENT);
+ mSize = size;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mSize;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mSize;
+ }
+ }
}
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index f9f4e50..c8d3890 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -18,89 +18,49 @@
import android.annotation.TargetApi;
import android.appwidget.AppWidgetManager;
-import android.content.ClipDescription;
import android.content.Intent;
import android.content.pm.LauncherApps.PinItemRequest;
-import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.SystemClock;
-import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.widget.RemoteViews;
-import com.android.launcher3.DeleteDropTarget;
import com.android.launcher3.DragSource;
-import com.android.launcher3.DropTarget;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.PendingAddItemInfo;
-import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.folder.Folder;
import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.PendingItemDragHelper;
import com.android.launcher3.widget.WidgetAddFlowHandler;
-import java.util.UUID;
-
/**
* {@link DragSource} for handling drop from a different window. This object is initialized
* in the source window and is passed on to the Launcher activity as an Intent extra.
*/
@TargetApi(Build.VERSION_CODES.O)
-public class PinItemDragListener
- implements Parcelable, View.OnDragListener, DragSource, DragOptions.PreDragCondition {
+public class PinItemDragListener extends BaseItemDragListener implements Parcelable {
- private static final String TAG = "PinItemDragListener";
-
- private static final String MIME_TYPE_PREFIX = "com.android.launcher3.drag_and_drop/";
public static final String EXTRA_PIN_ITEM_DRAG_LISTENER = "pin_item_drag_listener";
private final PinItemRequest mRequest;
- // Position of preview relative to the touch location
- private final Rect mPreviewRect;
-
- private final int mPreviewBitmapWidth;
- private final int mPreviewViewWidth;
-
- // Randomly generated id used to verify the drag event.
- private final String mId;
-
- private Launcher mLauncher;
- private DragController mDragController;
- private long mDragStartTime;
-
public PinItemDragListener(PinItemRequest request, Rect previewRect,
int previewBitmapWidth, int previewViewWidth) {
+ super(previewRect, previewBitmapWidth, previewViewWidth);
mRequest = request;
- mPreviewRect = previewRect;
- mPreviewBitmapWidth = previewBitmapWidth;
- mPreviewViewWidth = previewViewWidth;
- mId = UUID.randomUUID().toString();
}
private PinItemDragListener(Parcel parcel) {
+ super(parcel);
mRequest = PinItemRequest.CREATOR.createFromParcel(parcel);
- mPreviewRect = Rect.CREATOR.createFromParcel(parcel);
- mPreviewBitmapWidth = parcel.readInt();
- mPreviewViewWidth = parcel.readInt();
- mId = parcel.readString();
- }
-
- public String getMimeType() {
- return MIME_TYPE_PREFIX + mId;
}
@Override
@@ -110,45 +70,20 @@
@Override
public void writeToParcel(Parcel parcel, int i) {
+ super.writeToParcel(parcel, i);
mRequest.writeToParcel(parcel, i);
- mPreviewRect.writeToParcel(parcel, i);
- parcel.writeInt(mPreviewBitmapWidth);
- parcel.writeInt(mPreviewViewWidth);
- parcel.writeString(mId);
- }
-
- public void setLauncher(Launcher launcher) {
- mLauncher = launcher;
- mDragController = launcher.getDragController();
}
@Override
- public boolean onDrag(View view, DragEvent event) {
- if (mLauncher == null || mDragController == null) {
- postCleanup();
- return false;
- }
- if (event.getAction() == DragEvent.ACTION_DRAG_STARTED) {
- if (onDragStart(event)) {
- return true;
- } else {
- postCleanup();
- return false;
- }
- }
- return mDragController.onDragEvent(mDragStartTime, event);
- }
-
- private boolean onDragStart(DragEvent event) {
+ protected boolean onDragStart(DragEvent event) {
if (!mRequest.isValid()) {
return false;
}
- ClipDescription desc = event.getClipDescription();
- if (desc == null || !desc.hasMimeType(getMimeType())) {
- Log.e(TAG, "Someone started a dragAndDrop before us.");
- return false;
- }
+ return super.onDragStart(event);
+ }
+ @Override
+ protected PendingItemDragHelper createDragHelper() {
final PendingAddItemInfo item;
if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT) {
item = new PendingAddShortcutInfo(
@@ -170,109 +105,17 @@
View view = new View(mLauncher);
view.setTag(item);
- Point downPos = new Point((int) event.getX(), (int) event.getY());
- DragOptions options = new DragOptions();
- options.systemDndStartPoint = downPos;
- options.preDragCondition = this;
-
- // We use drag event position as the screenPos for the preview image. Since mPreviewRect
- // already includes the view position relative to the drag event on the source window,
- // and the absolute position (position relative to the screen) of drag event is same
- // across windows, using drag position here give a good estimate for relative position
- // to source window.
PendingItemDragHelper dragHelper = new PendingItemDragHelper(view);
if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_APPWIDGET) {
dragHelper.setPreview(getPreview(mRequest));
}
-
- dragHelper.startDrag(new Rect(mPreviewRect),
- mPreviewBitmapWidth, mPreviewViewWidth, downPos, this, options);
- mDragStartTime = SystemClock.uptimeMillis();
- return true;
- }
-
- @Override
- public boolean shouldStartDrag(double distanceDragged) {
- // Stay in pre-drag mode, if workspace is locked.
- return !mLauncher.isWorkspaceLocked();
- }
-
- @Override
- public void onPreDragStart(DropTarget.DragObject dragObject) {
- // The predrag starts when the workspace is not yet loaded. In some cases we set
- // the dragLayer alpha to 0 to have a nice fade-in animation. But that will prevent the
- // dragView from being visible. Instead just skip the fade-in animation here.
- mLauncher.getDragLayer().setAlpha(1);
-
- dragObject.dragView.setColor(
- mLauncher.getResources().getColor(R.color.delete_target_hover_tint));
- }
-
- @Override
- public void onPreDragEnd(DropTarget.DragObject dragObject, boolean dragStarted) {
- if (dragStarted) {
- dragObject.dragView.setColor(0);
- }
- }
-
- @Override
- public boolean supportsAppInfoDropTarget() {
- return false;
- }
-
- @Override
- public boolean supportsDeleteDropTarget() {
- return false;
- }
-
- @Override
- public float getIntrinsicIconScaleFactor() {
- return 1f;
- }
-
- @Override
- public void onDropCompleted(View target, DropTarget.DragObject d, boolean isFlingToDelete,
- boolean success) {
- if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() &&
- !(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
- // Exit spring loaded mode if we have not successfully dropped or have not handled the
- // drop in Workspace
- mLauncher.exitSpringLoadedDragModeDelayed(true,
- Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
- }
-
- if (!success) {
- d.deferDragViewCleanupPostAnimation = false;
- }
- postCleanup();
+ return dragHelper;
}
@Override
public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
LauncherLogProto.Target targetParent) {
- targetParent.containerType = ContainerType.PINITEM;
- }
-
- private void postCleanup() {
- if (mLauncher != null) {
- // Remove any drag params from the launcher intent since the drag operation is complete.
- Intent newIntent = new Intent(mLauncher.getIntent());
- newIntent.removeExtra(EXTRA_PIN_ITEM_DRAG_LISTENER);
- mLauncher.setIntent(newIntent);
- }
-
- new Handler(Looper.getMainLooper()).post(new Runnable() {
- @Override
- public void run() {
- removeListener();
- }
- });
- }
-
- public void removeListener() {
- if (mLauncher != null) {
- mLauncher.getDragLayer().setOnDragListener(null);
- }
+ targetParent.containerType = LauncherLogProto.ContainerType.PINITEM;
}
public static RemoteViews getPreview(PinItemRequest request) {
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java b/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java
index 21d5b27..de614f0 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java
@@ -24,15 +24,13 @@
import android.util.Log;
import android.util.Pair;
import android.util.Range;
-import android.util.SparseIntArray;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.WallpaperColorsCompat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.Arrays;
+import java.util.LinkedList;
import java.util.List;
/**
@@ -52,20 +50,18 @@
private static final float FIT_WEIGHT_S = 1.0f;
private static final float FIT_WEIGHT_L = 10.0f;
- // When extracting the main color, only consider colors
- // present in at least MIN_COLOR_OCCURRENCE of the image
- private static final float MIN_COLOR_OCCURRENCE = 0.1f;
-
// Temporary variable to avoid allocations
- private final float[] mTmpHSL = new float[3];
+ private float[] mTmpHSL = new float[3];
- public @Nullable Pair<Integer, Integer> extractInto(WallpaperColorsCompat wallpaperColors) {
- if (wallpaperColors == null) {
+ public @Nullable Pair<Integer, Integer> extractInto(WallpaperColorsCompat inWallpaperColors) {
+ if (inWallpaperColors == null) {
return null;
}
- SparseIntArray colorsArray = wallpaperColors.getColors();
- if (colorsArray.size() == 0) {
+ final List<Integer> mainColors = getMainColors(inWallpaperColors);
+ final int mainColorsSize = mainColors.size();
+
+ if (mainColorsSize == 0) {
return null;
}
// Tonal is not really a sort, it takes a color from the extracted
@@ -73,35 +69,17 @@
// palettes. The best fit is tweaked to be closer to the source color
// and replaces the original palette
- List<Pair<Integer, Integer>> colors = new ArrayList<>(colorsArray.size());
- for (int i = colorsArray.size() - 1; i >= 0; i--) {
- colors.add(Pair.create(colorsArray.keyAt(i), colorsArray.valueAt(i)));
- }
-
- // First find the most representative color in the image
- populationSort(colors);
- // Calculate total
- int total = 0;
- for (Pair<Integer, Integer> weightedColor : colors) {
- total += weightedColor.second;
- }
-
- // Get bright colors that occur often enough in this image
- Pair<Integer, Integer> bestColor = null;
- float[] hsl = new float[3];
- for (Pair<Integer, Integer> weightedColor : colors) {
- float colorOccurrence = weightedColor.second / (float) total;
- if (colorOccurrence < MIN_COLOR_OCCURRENCE) {
- break;
- }
-
- int colorValue = weightedColor.first;
+ // Get the most preeminent, non-blacklisted color.
+ Integer bestColor = 0;
+ final float[] hsl = new float[3];
+ for (int i = 0; i < mainColorsSize; i++) {
+ final int colorValue = mainColors.get(i);
ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue),
Color.blue(colorValue), hsl);
// Stop when we find a color that meets our criteria
if (!isBlacklisted(hsl)) {
- bestColor = weightedColor;
+ bestColor = colorValue;
break;
}
}
@@ -111,7 +89,7 @@
return null;
}
- int colorValue = bestColor.first;
+ int colorValue = bestColor;
ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
hsl);
@@ -120,8 +98,7 @@
hsl[0] /= 360f;
// Find the palette that contains the closest color
- TonalPalette palette = findTonalPalette(hsl[0]);
-
+ TonalPalette palette = findTonalPalette(hsl[0], hsl[1]);
if (palette == null) {
Log.w(TAG, "Could not find a tonal palette!");
return null;
@@ -142,9 +119,20 @@
final int textInversionIndex = h.length - 3;
- // best fit + a 2 colors offset
- int primaryIndex = fitIndex;
- int secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+ int primaryIndex;
+ int secondaryIndex;
+
+ // Dark colors:
+ // Stops at 4th color, only lighter if dark text is supported
+ if (fitIndex < 2) {
+ primaryIndex = 0;
+ } else if (fitIndex < textInversionIndex) {
+ primaryIndex = Math.min(fitIndex, 3);
+ } else {
+ primaryIndex = h.length - 1;
+ }
+ secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+
int mainColor = getColorInt(primaryIndex, h, s, l);
int secondaryColor = getColorInt(secondaryIndex, h, s, l);
@@ -172,15 +160,6 @@
return false;
}
- private static void populationSort(@NonNull List<Pair<Integer, Integer>> wallpaperColors) {
- Collections.sort(wallpaperColors, new Comparator<Pair<Integer, Integer>>() {
- @Override
- public int compare(Pair<Integer, Integer> a, Pair<Integer, Integer> b) {
- return b.second - a.second;
- }
- });
- }
-
/**
* Offsets all colors by a delta, clamping values that go beyond what's
* supported on the color space.
@@ -230,11 +209,19 @@
}
@Nullable
- private static TonalPalette findTonalPalette(float h) {
+ private static TonalPalette findTonalPalette(float h, float s) {
+ // Fallback to a grey palette if the color is too desaturated.
+ // This avoids hue shifts.
+ if (s < 0.05f) {
+ return GREY_PALETTE;
+ }
+
TonalPalette best = null;
float error = Float.POSITIVE_INFINITY;
- for (TonalPalette candidate : TONAL_PALETTES) {
+ for (int i = 0; i < TONAL_PALETTES.length; i++) {
+ final TonalPalette candidate = TONAL_PALETTES[i];
+
if (h >= candidate.minHue && h <= candidate.maxHue) {
best = candidate;
break;
@@ -282,6 +269,12 @@
final float maxHue;
TonalPalette(float[] h, float[] s, float[] l) {
+ if (h.length != s.length || s.length != l.length) {
+ throw new IllegalArgumentException("All arrays should have the same size. h: "
+ + Arrays.toString(h) + " s: " + Arrays.toString(s) + " l: "
+ + Arrays.toString(l));
+ }
+
this.h = h;
this.s = s;
this.l = l;
@@ -304,271 +297,280 @@
// a best fit. Each palette is defined as 22 HSL colors
private static final TonalPalette[] TONAL_PALETTES = {
new TonalPalette(
- new float[]{0.991f, 0.9833333333333333f, 0f, 0f, 0f, 0.01134380453752181f,
- 0.015625000000000003f, 0.024193548387096798f, 0.027397260273972573f,
- 0.017543859649122865f},
- new float[]{1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.2f, 0.27450980392156865f, 0.34901960784313724f,
- 0.4235294117647059f, 0.5490196078431373f, 0.6254901960784314f,
- 0.6862745098039216f, 0.7568627450980392f, 0.8568627450980393f,
- 0.9254901960784314f}
+ new float[] {1f, 1f, 0.991f, 0.991f, 0.9833333333333333f, 0f, 0f, 0f,
+ 0.01134380453752181f, 0.015625000000000003f, 0.024193548387096798f,
+ 0.027397260273972573f, 0.017543859649122865f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f,
+ 1f},
+ new float[] {0.04f, 0.09f, 0.14f, 0.2f, 0.27450980392156865f,
+ 0.34901960784313724f, 0.4235294117647059f, 0.5490196078431373f,
+ 0.6254901960784314f, 0.6862745098039216f, 0.7568627450980392f,
+ 0.8568627450980393f, 0.9254901960784314f}
),
new TonalPalette(
- new float[]{0.6385767790262171f, 0.6301169590643275f, 0.6223958333333334f,
- 0.6151079136690647f, 0.6065400843881856f, 0.5986964618249534f,
- 0.5910746812386157f, 0.5833333333333334f, 0.5748031496062993f,
- 0.5582010582010583f},
- new float[]{1f, 1f, 0.9014084507042253f, 0.8128654970760234f,
- 0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f,
- 1f, 1f, 1f},
- new float[]{0.17450980392156862f, 0.2235294117647059f, 0.2784313725490196f,
- 0.3352941176470588f, 0.388235294117647f, 0.44901960784313727f,
- 0.5392156862745098f, 0.6509803921568628f, 0.7509803921568627f,
- 0.8764705882352941f}
+ new float[] {0.638f, 0.638f, 0.6385767790262171f, 0.6301169590643275f,
+ 0.6223958333333334f, 0.6151079136690647f, 0.6065400843881856f,
+ 0.5986964618249534f, 0.5910746812386157f, 0.5833333333333334f,
+ 0.5748031496062993f, 0.5582010582010583f},
+ new float[] {1f, 1f, 1f, 1f, 0.9014084507042253f, 0.8128654970760234f,
+ 0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f, 1f, 1f,
+ 1f},
+ new float[] {0.05f, 0.12f, 0.17450980392156862f, 0.2235294117647059f,
+ 0.2784313725490196f, 0.3352941176470588f, 0.388235294117647f,
+ 0.44901960784313727f, 0.5392156862745098f, 0.6509803921568628f,
+ 0.7509803921568627f, 0.8764705882352941f}
),
new TonalPalette(
- new float[]{0.5669934640522876f, 0.5748031496062993f,
+ new float[] {0.563f, 0.569f, 0.5666f, 0.5669934640522876f, 0.5748031496062993f,
0.5595238095238095f, 0.5473118279569893f, 0.5393258426966292f,
0.5315955766192734f, 0.524031007751938f, 0.5154711673699016f,
0.508080808080808f, 0.5f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f, 1f},
- new float[]{0.2f, 0.24901960784313726f, 0.27450980392156865f,
- 0.30392156862745096f, 0.34901960784313724f, 0.4137254901960784f,
- 0.47647058823529415f, 0.5352941176470588f, 0.6764705882352942f, 0.8f}
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f,
+ 1f},
+ new float[] {0.07f, 0.12f, 0.16f, 0.2f, 0.24901960784313726f,
+ 0.27450980392156865f, 0.30392156862745096f, 0.34901960784313724f,
+ 0.4137254901960784f, 0.47647058823529415f, 0.5352941176470588f,
+ 0.6764705882352942f, 0.8f}
),
new TonalPalette(
- new float[]{0.5082304526748972f, 0.5069444444444444f, 0.5f, 0.5f,
- 0.5f, 0.48724954462659376f, 0.4800347222222222f,
- 0.4755134281200632f, 0.4724409448818897f, 0.4671052631578947f},
- new float[]{1f, 0.8888888888888887f, 0.9242424242424242f, 1f, 1f,
- 0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f},
- new float[]{0.1588235294117647f, 0.21176470588235297f,
- 0.25882352941176473f, 0.3f, 0.34901960784313724f,
+ new float[] {0.508f, 0.511f, 0.508f, 0.508f, 0.5082304526748972f,
+ 0.5069444444444444f, 0.5f, 0.5f, 0.5f, 0.48724954462659376f,
+ 0.4800347222222222f, 0.4755134281200632f, 0.4724409448818897f,
+ 0.4671052631578947f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 0.8888888888888887f, 0.9242424242424242f, 1f,
+ 1f, 0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f},
+ new float[] {0.04f, 0.06f, 0.08f, 0.12f, 0.1588235294117647f,
+ 0.21176470588235297f, 0.25882352941176473f, 0.3f, 0.34901960784313724f,
0.44117647058823534f, 0.5215686274509804f, 0.5862745098039216f,
0.7509803921568627f, 0.8509803921568627f}
),
new TonalPalette(
- new float[]{0.3333333333333333f, 0.3333333333333333f,
+ new float[] {0.333f, 0.333f, 0.333f, 0.3333333333333333f, 0.3333333333333333f,
0.34006734006734f, 0.34006734006734f, 0.34006734006734f,
0.34259259259259256f, 0.3475783475783476f, 0.34767025089605735f,
0.3467741935483871f, 0.3703703703703704f},
- new float[]{0.6703296703296703f, 0.728813559322034f,
+ new float[] {0.70f, 0.72f, 0.69f, 0.6703296703296703f, 0.728813559322034f,
0.5657142857142856f, 0.5076923076923077f, 0.3944223107569721f,
0.6206896551724138f, 0.8931297709923666f, 1f, 1f, 1f},
- new float[]{0.1784313725490196f, 0.23137254901960785f,
+ new float[] {0.05f, 0.08f, 0.14f, 0.1784313725490196f, 0.23137254901960785f,
0.3431372549019608f, 0.38235294117647056f, 0.49215686274509807f,
0.6588235294117647f, 0.7431372549019608f, 0.8176470588235294f,
0.8784313725490196f, 0.9294117647058824f}
),
new TonalPalette(
- new float[]{0.162280701754386f, 0.15032679738562088f,
+ new float[] {0.161f, 0.163f, 0.163f, 0.162280701754386f, 0.15032679738562088f,
0.15879265091863518f, 0.16236559139784948f, 0.17443868739205526f,
- 0.17824074074074076f, 0.18674698795180725f,
- 0.18692449355432778f, 0.1946778711484594f, 0.18604651162790695f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.14901960784313725f, 0.2f, 0.24901960784313726f,
- 0.30392156862745096f, 0.3784313725490196f, 0.4235294117647059f,
- 0.48823529411764705f, 0.6450980392156863f, 0.7666666666666666f,
- 0.8313725490196078f}
+ 0.17824074074074076f, 0.18674698795180725f, 0.18692449355432778f,
+ 0.1946778711484594f, 0.18604651162790695f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+ new float[] {0.05f, 0.08f, 0.11f, 0.14901960784313725f, 0.2f,
+ 0.24901960784313726f, 0.30392156862745096f, 0.3784313725490196f,
+ 0.4235294117647059f, 0.48823529411764705f, 0.6450980392156863f,
+ 0.7666666666666666f, 0.8313725490196078f}
),
new TonalPalette(
- new float[]{0.10619469026548674f, 0.11924686192468618f,
- 0.13046448087431692f, 0.14248366013071895f, 0.1506024096385542f,
- 0.16220238095238093f, 0.16666666666666666f,
+ new float[] {0.108f, 0.105f, 0.105f, 0.105f, 0.10619469026548674f,
+ 0.11924686192468618f, 0.13046448087431692f, 0.14248366013071895f,
+ 0.1506024096385542f, 0.16220238095238093f, 0.16666666666666666f,
0.16666666666666666f, 0.162280701754386f, 0.15686274509803924f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.44313725490196076f, 0.46862745098039216f,
- 0.47843137254901963f, 0.5f, 0.5117647058823529f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+ new float[] {0.17f, 0.22f, 0.28f, 0.35f, 0.44313725490196076f,
+ 0.46862745098039216f, 0.47843137254901963f, 0.5f, 0.5117647058823529f,
0.5607843137254902f, 0.6509803921568628f, 0.7509803921568627f,
0.8509803921568627f, 0.9f}
),
new TonalPalette(
- new float[]{0.03561253561253561f, 0.05098039215686275f,
- 0.07516339869281045f, 0.09477124183006536f, 0.1150326797385621f,
- 0.134640522875817f, 0.14640522875816991f, 0.1582397003745319f,
- 0.15773809523809523f, 0.15359477124183002f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.4588235294117647f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
- 0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f}
+ new float[] {0.036f, 0.036f, 0.036f, 0.036f, 0.03561253561253561f,
+ 0.05098039215686275f, 0.07516339869281045f, 0.09477124183006536f,
+ 0.1150326797385621f, 0.134640522875817f, 0.14640522875816991f,
+ 0.1582397003745319f, 0.15773809523809523f, 0.15359477124183002f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+ new float[] {0.19f, 0.26f, 0.34f, 0.39f, 0.4588235294117647f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f}
),
new TonalPalette(
- new float[]{0.9596491228070175f, 0.9593837535014005f,
+ new float[] {0.955f, 0.961f, 0.958f, 0.9596491228070175f, 0.9593837535014005f,
0.9514767932489452f, 0.943859649122807f, 0.9396825396825397f,
0.9395424836601307f, 0.9393939393939394f, 0.9362745098039216f,
0.9754098360655739f, 0.9824561403508771f},
- new float[]{0.84070796460177f, 0.8206896551724138f,
+ new float[] {0.87f, 0.85f, 0.85f, 0.84070796460177f, 0.8206896551724138f,
0.7979797979797981f, 0.7661290322580644f, 0.9051724137931036f,
1f, 1f, 1f, 1f, 1f},
- new float[]{0.22156862745098038f, 0.2843137254901961f,
+ new float[] {0.06f, 0.11f, 0.16f, 0.22156862745098038f, 0.2843137254901961f,
0.388235294117647f, 0.48627450980392156f, 0.5450980392156863f,
0.6f, 0.6764705882352942f, 0.8f, 0.8803921568627451f,
0.9254901960784314f}
),
new TonalPalette(
- new float[]{0.841025641025641f, 0.8333333333333334f,
+ new float[] {0.866f, 0.855f, 0.841025641025641f, 0.8333333333333334f,
0.8285256410256411f, 0.821522309711286f, 0.8083333333333333f,
0.8046594982078853f, 0.8005822416302766f, 0.7842377260981912f,
0.7771084337349398f, 0.7747747747747749f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f,
0.737142857142857f, 0.6434108527131781f, 0.46835443037974644f},
- new float[]{0.12745098039215685f, 0.15490196078431373f,
+ new float[] {0.05f, 0.08f, 0.12745098039215685f, 0.15490196078431373f,
0.20392156862745098f, 0.24901960784313726f, 0.3137254901960784f,
- 0.36470588235294116f, 0.44901960784313727f,
- 0.6568627450980392f, 0.7470588235294118f, 0.8450980392156863f}
+ 0.36470588235294116f, 0.44901960784313727f, 0.6568627450980392f,
+ 0.7470588235294118f, 0.8450980392156863f}
),
new TonalPalette(
- new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
- new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
- new float[]{0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
- 0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
- 0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f}
- ),
- new TonalPalette(
- new float[]{0.955952380952381f, 0.9681069958847737f,
- 0.9760479041916167f, 0.9873563218390804f, 0f, 0f,
+ new float[] {0.925f, 0.93f, 0.938f, 0.947f, 0.955952380952381f,
+ 0.9681069958847737f, 0.9760479041916167f, 0.9873563218390804f, 0f, 0f,
0.009057971014492771f, 0.026748971193415648f,
0.041666666666666616f, 0.05303030303030304f},
- new float[]{1f, 0.8350515463917526f, 0.6929460580912863f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 0.8350515463917526f, 0.6929460580912863f,
0.6387665198237885f, 0.6914893617021276f, 0.7583892617449666f,
0.8070175438596495f, 0.9310344827586209f, 1f, 1f},
- new float[]{0.27450980392156865f, 0.3803921568627451f,
- 0.4725490196078432f, 0.5549019607843138f, 0.6313725490196078f,
- 0.707843137254902f, 0.7764705882352941f, 0.8294117647058823f,
- 0.9058823529411765f, 0.9568627450980391f}
+ new float[] {0.10f, 0.13f, 0.17f, 0.2f, 0.27450980392156865f,
+ 0.3803921568627451f, 0.4725490196078432f, 0.5549019607843138f,
+ 0.6313725490196078f, 0.707843137254902f, 0.7764705882352941f,
+ 0.8294117647058823f, 0.9058823529411765f, 0.9568627450980391f}
),
new TonalPalette(
- new float[]{0.7514619883040936f, 0.7679738562091503f,
+ new float[] {0.733f, 0.736f, 0.744f, 0.7514619883040936f, 0.7679738562091503f,
0.7802083333333333f, 0.7844311377245509f, 0.796875f,
0.8165618448637316f, 0.8487179487179487f, 0.8582375478927203f,
0.8562091503267975f, 0.8666666666666667f},
- new float[]{1f, 1f, 0.8163265306122449f, 0.6653386454183268f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 0.8163265306122449f, 0.6653386454183268f,
0.7547169811320753f, 0.929824561403509f, 0.9558823529411766f,
0.9560439560439562f, 1f, 1f},
- new float[]{0.2235294117647059f, 0.3f, 0.38431372549019605f,
- 0.492156862745098f, 0.5843137254901961f, 0.6647058823529411f,
- 0.7333333333333334f, 0.8215686274509804f, 0.9f,
+ new float[] {0.07f, 0.12f, 0.17f, 0.2235294117647059f, 0.3f,
+ 0.38431372549019605f, 0.492156862745098f, 0.5843137254901961f,
+ 0.6647058823529411f, 0.7333333333333334f, 0.8215686274509804f, 0.9f,
0.9411764705882353f}
),
new TonalPalette(
- new float[]{0.6666666666666666f, 0.6666666666666666f,
+ new float[] {0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
0.6666666666666666f, 0.6666666666666666f},
- new float[]{0.24590163934426232f, 0.17880794701986752f,
+ new float[] {0.25f, 0.24590163934426232f, 0.17880794701986752f,
0.14606741573033713f, 0.13761467889908252f, 0.14893617021276592f,
- 0.16756756756756758f, 0.20312500000000017f,
- 0.26086956521739135f, 0.29999999999999966f, 0.5000000000000004f},
- new float[]{0.2392156862745098f, 0.296078431372549f,
+ 0.16756756756756758f, 0.20312500000000017f, 0.26086956521739135f,
+ 0.29999999999999966f, 0.5000000000000004f},
+ new float[] {0.18f, 0.2392156862745098f, 0.296078431372549f,
0.34901960784313724f, 0.4274509803921569f, 0.5392156862745098f,
0.6372549019607843f, 0.7490196078431373f, 0.8196078431372549f,
0.8823529411764706f, 0.9372549019607843f}
),
new TonalPalette(
- new float[]{0.9678571428571429f, 0.9944812362030905f, 0f, 0f,
+ new float[] {0.938f, 0.944f, 0.952f, 0.961f, 0.9678571428571429f,
+ 0.9944812362030905f, 0f, 0f,
0.0047348484848484815f, 0.00316455696202532f, 0f,
0.9980392156862745f, 0.9814814814814816f, 0.9722222222222221f},
- new float[]{1f, 0.7023255813953488f, 0.6638655462184874f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 0.7023255813953488f, 0.6638655462184874f,
0.6521739130434782f, 0.7719298245614035f, 0.8315789473684211f,
0.6867469879518071f, 0.7264957264957265f, 0.8181818181818182f,
0.8181818181818189f},
- new float[]{0.27450980392156865f, 0.4215686274509804f,
+ new float[] {0.08f, 0.13f, 0.18f, 0.23f, 0.27450980392156865f,
+ 0.4215686274509804f,
0.4666666666666667f, 0.503921568627451f, 0.5529411764705883f,
0.6274509803921569f, 0.6745098039215687f, 0.7705882352941176f,
0.892156862745098f, 0.9568627450980391f}
),
new TonalPalette(
- new float[]{0.9052287581699346f, 0.9112021857923498f, 0.9270152505446624f,
- 0.9343137254901961f, 0.9391534391534391f, 0.9437984496124031f,
- 0.943661971830986f, 0.9438943894389439f, 0.9426229508196722f,
- 0.9444444444444444f},
- new float[]{1f, 0.8133333333333332f, 0.7927461139896375f, 0.7798165137614679f,
- 0.7777777777777779f, 0.8190476190476191f, 0.8255813953488372f,
- 0.8211382113821142f, 0.8133333333333336f, 0.8000000000000006f},
- new float[]{0.2f, 0.29411764705882354f, 0.3784313725490196f,
- 0.42745098039215684f, 0.4764705882352941f, 0.5882352941176471f,
- 0.6627450980392157f, 0.7588235294117647f, 0.8529411764705882f,
- 0.9411764705882353f}
+ new float[] {0.88f, 0.888f, 0.897f, 0.9052287581699346f, 0.9112021857923498f,
+ 0.9270152505446624f, 0.9343137254901961f, 0.9391534391534391f,
+ 0.9437984496124031f, 0.943661971830986f, 0.9438943894389439f,
+ 0.9426229508196722f, 0.9444444444444444f},
+ new float[] {1f, 1f, 1f, 1f, 0.8133333333333332f, 0.7927461139896375f,
+ 0.7798165137614679f, 0.7777777777777779f, 0.8190476190476191f,
+ 0.8255813953488372f, 0.8211382113821142f, 0.8133333333333336f,
+ 0.8000000000000006f},
+ new float[] {0.08f, 0.12f, 0.16f, 0.2f, 0.29411764705882354f,
+ 0.3784313725490196f, 0.42745098039215684f, 0.4764705882352941f,
+ 0.5882352941176471f, 0.6627450980392157f, 0.7588235294117647f,
+ 0.8529411764705882f, 0.9411764705882353f}
),
new TonalPalette(
- new float[]{0.6884057971014492f, 0.6974789915966387f, 0.7079889807162534f,
- 0.7154471544715447f, 0.7217741935483872f, 0.7274143302180687f,
- 0.7272727272727273f, 0.7258064516129031f, 0.7252252252252251f,
- 0.7333333333333333f},
- new float[]{0.8214285714285715f, 0.6878612716763006f, 0.6080402010050251f,
- 0.5774647887323943f, 0.5391304347826086f, 0.46724890829694316f,
- 0.4680851063829788f, 0.462686567164179f, 0.45679012345678977f,
- 0.4545454545454551f},
- new float[]{0.2196078431372549f, 0.33921568627450976f, 0.39019607843137255f,
- 0.4176470588235294f, 0.45098039215686275f,
+ new float[] {0.669f, 0.680f, 0.6884057971014492f, 0.6974789915966387f,
+ 0.7079889807162534f, 0.7154471544715447f, 0.7217741935483872f,
+ 0.7274143302180687f, 0.7272727272727273f, 0.7258064516129031f,
+ 0.7252252252252251f, 0.7333333333333333f},
+ new float[] {0.81f, 0.81f, 0.8214285714285715f, 0.6878612716763006f,
+ 0.6080402010050251f, 0.5774647887323943f, 0.5391304347826086f,
+ 0.46724890829694316f, 0.4680851063829788f, 0.462686567164179f,
+ 0.45679012345678977f, 0.4545454545454551f},
+ new float[] {0.12f, 0.16f, 0.2196078431372549f, 0.33921568627450976f,
+ 0.39019607843137255f, 0.4176470588235294f, 0.45098039215686275f,
0.5509803921568628f, 0.6313725490196078f, 0.7372549019607844f,
0.8411764705882353f, 0.9352941176470588f}
),
new TonalPalette(
- new float[]{0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f,
+ new float[] {0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f,
0.6441441441441442f, 0.6432748538011696f, 0.6416666666666667f,
0.6402439024390243f, 0.6412429378531074f, 0.6435185185185186f,
0.6428571428571429f},
- new float[]{0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f,
+ new float[] {0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f,
0.5362318840579711f, 0.5f, 0.4424778761061947f, 0.44086021505376327f,
- 0.44360902255639095f,
- 0.4499999999999997f, 0.4375000000000006f},
- new float[]{0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f,
+ 0.44360902255639095f, 0.4499999999999997f, 0.4375000000000006f},
+ new float[] {0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f,
0.40588235294117647f, 0.44705882352941173f,
0.5568627450980392f, 0.6352941176470588f, 0.7392156862745098f,
0.8431372549019608f, 0.9372549019607843f}
),
new TonalPalette(
- new float[]{0.46732026143790845f, 0.4718614718614719f, 0.4793650793650794f,
- 0.48071625344352614f, 0.4829683698296837f, 0.484375f,
- 0.4841269841269842f, 0.48444444444444457f, 0.48518518518518516f,
- 0.4907407407407408f},
- new float[]{1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f,
- 0.41899441340782106f, 0.4128440366972478f,
- 0.4090909090909088f},
- new float[]{0.1f, 0.15098039215686274f, 0.20588235294117646f,
+ new float[] {0.469f, 0.46732026143790845f, 0.4718614718614719f,
+ 0.4793650793650794f, 0.48071625344352614f, 0.4829683698296837f,
+ 0.484375f, 0.4841269841269842f, 0.48444444444444457f,
+ 0.48518518518518516f, 0.4907407407407408f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f,
+ 0.41899441340782106f, 0.4128440366972478f, 0.4090909090909088f},
+ new float[] {0.07f, 0.1f, 0.15098039215686274f, 0.20588235294117646f,
0.2372549019607843f, 0.26862745098039215f, 0.4f, 0.5078431372549019f,
0.6490196078431372f, 0.7862745098039216f, 0.9137254901960784f}
),
new TonalPalette(
- new float[]{0.5444444444444444f, 0.5555555555555556f, 0.5555555555555556f,
- 0.553763440860215f, 0.5526315789473684f, 0.5555555555555556f,
- 0.5555555555555555f, 0.5555555555555556f, 0.5512820512820514f,
- 0.5666666666666667f},
- new float[]{0.24590163934426232f, 0.19148936170212766f, 0.1791044776119403f,
- 0.18343195266272191f, 0.18446601941747576f,
+ new float[] {0.542f, 0.5444444444444444f, 0.5555555555555556f,
+ 0.5555555555555556f, 0.553763440860215f, 0.5526315789473684f,
+ 0.5555555555555556f, 0.5555555555555555f, 0.5555555555555556f,
+ 0.5512820512820514f, 0.5666666666666667f},
+ new float[] {0.25f, 0.24590163934426232f, 0.19148936170212766f,
+ 0.1791044776119403f, 0.18343195266272191f, 0.18446601941747576f,
0.1538461538461539f, 0.15625000000000003f, 0.15328467153284678f,
0.15662650602409653f, 0.151515151515151f},
- new float[]{0.1196078431372549f, 0.1843137254901961f, 0.2627450980392157f,
+ new float[] {0.05f, 0.1196078431372549f, 0.1843137254901961f,
+ 0.2627450980392157f,
0.33137254901960783f, 0.403921568627451f, 0.5411764705882354f,
0.6235294117647059f, 0.7313725490196079f, 0.8372549019607843f,
0.9352941176470588f}
),
new TonalPalette(
- new float[]{0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f,
+ new float[] {0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f,
0.03947368421052631f, 0.04166666666666668f,
0.043650793650793655f, 0.04411764705882352f, 0.04166666666666652f,
0.04444444444444459f, 0.05555555555555529f},
- new float[]{0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f,
+ new float[] {0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f,
0.25675675675675674f, 0.2528735632183908f, 0.17500000000000002f,
0.15315315315315312f, 0.15189873417721522f,
0.15789473684210534f, 0.15789473684210542f},
- new float[]{0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f,
+ new float[] {0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f,
0.2901960784313725f, 0.3411764705882353f, 0.47058823529411764f,
0.5647058823529412f, 0.6901960784313725f, 0.8137254901960784f,
0.9254901960784314f}
),
new TonalPalette(
- new float[]{0.050884955752212385f, 0.07254901960784313f, 0.0934640522875817f,
+ new float[] {0.027f, 0.03f, 0.038f, 0.044f, 0.050884955752212385f,
+ 0.07254901960784313f, 0.0934640522875817f,
0.10457516339869281f, 0.11699346405228758f,
0.1255813953488372f, 0.1268939393939394f, 0.12533333333333332f,
0.12500000000000003f, 0.12777777777777777f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.44313725490196076f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5784313725490196f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+ new float[] {0.25f, 0.3f, 0.35f, 0.4f, 0.44313725490196076f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5784313725490196f,
0.6549019607843137f, 0.7549019607843137f, 0.8509803921568627f,
0.9411764705882353f}
)
};
+ private static final TonalPalette GREY_PALETTE = new TonalPalette(
+ new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+ new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+ new float[]{0.08f, 0.11f, 0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
+ 0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
+ 0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f}
+ );
+
@SuppressWarnings("WeakerAccess")
static final ColorRange[] BLACKLISTED_COLORS = new ColorRange[] {
@@ -757,4 +759,17 @@
}
}
+ private static List<Integer> getMainColors(WallpaperColorsCompat wallpaperColors) {
+ LinkedList<Integer> colors = new LinkedList<>();
+ if (wallpaperColors.getPrimaryColor() != 0) {
+ colors.add(wallpaperColors.getPrimaryColor());
+ }
+ if (wallpaperColors.getSecondaryColor() != 0) {
+ colors.add(wallpaperColors.getSecondaryColor());
+ }
+ if (wallpaperColors.getTertiaryColor() != 0) {
+ colors.add(wallpaperColors.getTertiaryColor());
+ }
+ return colors;
+ }
}
diff --git a/src/com/android/launcher3/dynamicui/ExtractionUtils.java b/src/com/android/launcher3/dynamicui/ExtractionUtils.java
index 92cb5dc..cc0e0be 100644
--- a/src/com/android/launcher3/dynamicui/ExtractionUtils.java
+++ b/src/com/android/launcher3/dynamicui/ExtractionUtils.java
@@ -29,6 +29,7 @@
import android.support.v7.graphics.Palette;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
import java.util.List;
@@ -47,6 +48,9 @@
* Launcher will be notified in Launcher#onSettingsChanged(String, String).
*/
public static void startColorExtractionServiceIfNecessary(final Context context) {
+ if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ return;
+ }
// Run on a background thread, since the service is asynchronous anyway.
Utilities.THREAD_POOL_EXECUTOR.execute(new Runnable() {
@Override
@@ -60,6 +64,9 @@
/** Starts the {@link ColorExtractionService} without checking the wallpaper id */
public static void startColorExtractionService(Context context) {
+ if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ return;
+ }
JobScheduler jobScheduler = (JobScheduler) context.getSystemService(
Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(new JobInfo.Builder(Utilities.COLOR_EXTRACTION_JOB_ID,
diff --git a/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java b/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java
index e23f42f..512e89a 100644
--- a/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java
+++ b/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java
@@ -61,7 +61,7 @@
@Override
public void onColorsChanged(WallpaperColorsCompat colors, int which) {
- if (which == FLAG_SYSTEM) {
+ if ((which & FLAG_SYSTEM) != 0) {
boolean wasDarkTheme = mIsDark;
boolean didSupportDarkText = mSupportsDarkText;
update(colors);
@@ -78,7 +78,9 @@
mMainColor = FALLBACK_COLOR;
mSecondaryColor = FALLBACK_COLOR;
}
- mSupportsDarkText = wallpaperColors != null ? wallpaperColors.supportsDarkText() : false;
+ mSupportsDarkText = wallpaperColors != null
+ ? (wallpaperColors.getColorHints()
+ & WallpaperColorsCompat.HINT_SUPPORTS_DARK_TEXT) > 0 : false;
float[] hsl = new float[3];
ColorUtils.colorToHSL(mMainColor, hsl);
mIsDark = hsl[2] < 0.2f;
diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
index 0df787a..ff357c0 100644
--- a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
@@ -20,7 +20,7 @@
private float mBaselineIconScale;
@Override
- public void init(int availableSpace, int intrinsicIconSize, boolean rtl) {
+ public void init(int availableSpace, float intrinsicIconSize, boolean rtl) {
mAvailableSpace = availableSpace;
mRadius = ITEM_RADIUS_SCALE_FACTOR * availableSpace / 2f;
mIconSize = intrinsicIconSize;
@@ -29,8 +29,8 @@
}
@Override
- public FolderIcon.PreviewItemDrawingParams computePreviewItemDrawingParams(int index,
- int curNumItems, FolderIcon.PreviewItemDrawingParams params) {
+ public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
+ PreviewItemDrawingParams params) {
float totalScale = scaleForItem(index, curNumItems);
float transX;
@@ -47,7 +47,7 @@
}
if (params == null) {
- params = new FolderIcon.PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha);
+ params = new PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha);
} else {
params.update(transX, transY, totalScale);
params.overlayAlpha = overlayAlpha;
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 80338ca..3c7c698 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;
@@ -284,9 +283,6 @@
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
ShortcutInfo item = (ShortcutInfo) tag;
- if (!v.isInTouchMode()) {
- return false;
- }
mEmptyCellRank = item.rank;
mCurrentDragView = v;
@@ -336,6 +332,7 @@
if (mIsExternalDrag && mDragInProgress) {
completeDragExit();
}
+ mDragInProgress = false;
mDragController.removeDragListener(this);
}
@@ -356,13 +353,14 @@
@Override
public boolean onBackKey() {
- mFolderName.setHint(sHintText);
// Convert to a string here to ensure that no other state associated with the text field
// gets saved.
String newTitle = mFolderName.getText().toString();
mInfo.setTitle(newTitle);
mLauncher.getModelWriter().updateItemInDatabase(mInfo);
+ mFolderName.setHint(sDefaultFolderName.contentEquals(newTitle) ? sHintText : null);
+
Utilities.sendCustomAccessibilityEvent(
this, AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
getContext().getString(R.string.folder_renamed, newTitle));
@@ -459,8 +457,10 @@
if (!sDefaultFolderName.contentEquals(mInfo.title)) {
mFolderName.setText(mInfo.title);
+ mFolderName.setHint(null);
} else {
mFolderName.setText("");
+ mFolderName.setHint(sHintText);
}
// In case any children didn't come across during loading, clean up the folder accordingly
@@ -634,7 +634,9 @@
@Override
public void onAnimationStart(Animator animation) {
if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+ mFolderIcon.setBackgroundVisible(false);
mFolderIcon.drawLeaveBehindIfExists();
+ } else {
mFolderIcon.setVisibility(INVISIBLE);
}
@@ -788,8 +790,16 @@
clearFocus();
if (mFolderIcon != null) {
mFolderIcon.setVisibility(View.VISIBLE);
+ if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+ mFolderIcon.mFolderName.setTextVisibility(true);
+ mFolderIcon.setBackgroundVisible(true);
+ mFolderIcon.mBackground.fadeInBackgroundShadow();
+ }
if (wasAnimated) {
mFolderIcon.mBackground.animateBackgroundStroke();
+ if (mFolderIcon.hasBadge()) {
+ mFolderIcon.createBadgeScaleAnimator(0f, 1f).start();
+ }
mFolderIcon.requestFocus();
}
}
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index bee0bd4..3648c60 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -37,6 +37,7 @@
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.PropertyResetListener;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.util.Themes;
@@ -57,7 +58,7 @@
private GradientDrawable mFolderBackground;
private FolderIcon mFolderIcon;
- private FolderIcon.PreviewBackground mPreviewBackground;
+ private PreviewBackground mPreviewBackground;
private Context mContext;
private Launcher mLauncher;
@@ -70,8 +71,7 @@
private final TimeInterpolator mFolderInterpolator;
private final TimeInterpolator mLargeFolderPreviewItemInterpolator;
- private final FolderIcon.PreviewItemDrawingParams mTmpParams =
- new FolderIcon.PreviewItemDrawingParams(0, 0, 0, 0);
+ private final PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0);
private static final Property<View, Float> SCALE_PROPERTY =
new Property<View, Float>(Float.class, "scale") {
@@ -87,23 +87,6 @@
}
};
- private static final Property<List<BubbleTextView>, Integer> ITEMS_TEXT_COLOR_PROPERTY =
- new Property<List<BubbleTextView>, Integer>(Integer.class, "textColor") {
- @Override
- public Integer get(List<BubbleTextView> items) {
- return items.get(0).getCurrentTextColor();
- }
-
- @Override
- public void set(List<BubbleTextView> items, Integer color) {
- int size = items.size();
-
- for (int i = 0; i < size; ++i) {
- items.get(i).setTextColor(color);
- }
- }
- };
-
public FolderAnimationManager(Folder folder, boolean isOpening) {
mFolder = folder;
mContent = folder.mContent;
@@ -183,12 +166,6 @@
ColorUtils.setAlphaComponent(finalColor, mPreviewBackground.getBackgroundAlpha());
mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
- // Initialize the Folder items' text.
- final List<BubbleTextView> items = mFolder.getItemsOnCurrentPage();
- final int finalTextColor = Themes.getAttrColor(mContext, android.R.attr.textColorSecondary);
- ITEMS_TEXT_COLOR_PROPERTY.set(items, mIsOpening ? Color.TRANSPARENT
- : finalTextColor);
-
// Set up the reveal animation that clips the Folder.
int totalOffsetX = paddingOffsetX + previewItemOffsetX;
Rect startRect = new Rect(
@@ -203,21 +180,39 @@
// Create the animators.
AnimatorSet a = LauncherAnimUtils.createAnimatorSet();
+ // Initialize the Folder items' text.
+ PropertyResetListener colorResetListener = new PropertyResetListener(
+ BubbleTextView.TEXT_ALPHA_PROPERTY,
+ Color.alpha(Themes.getAttrColor(mContext, android.R.attr.textColorSecondary)));
+ for (BubbleTextView icon : mFolder.getItemsOnCurrentPage()) {
+ if (mIsOpening) {
+ icon.setTextVisibility(false);
+ }
+ ObjectAnimator anim = icon.createTextAlphaAnimator(mIsOpening);
+ anim.addListener(colorResetListener);
+ play(a, anim);
+ }
+
play(a, getAnimator(mFolder, View.TRANSLATION_X, xDistance, 0f));
play(a, getAnimator(mFolder, View.TRANSLATION_Y, yDistance, 0f));
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));
+ // Animate the elevation midway so that the shadow is not noticeable in the background.
+ int midDuration = mDuration / 2;
+ Animator z = getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0);
+ play(a, z, midDuration, midDuration);
+
a.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
- ITEMS_TEXT_COLOR_PROPERTY.set(items, finalTextColor);
mFolder.setTranslationX(0.0f);
mFolder.setTranslationY(0.0f);
+ mFolder.setTranslationZ(0.0f);
mFolder.setScaleX(1f);
mFolder.setScaleY(1f);
}
@@ -328,7 +323,12 @@
}
private void play(AnimatorSet as, Animator a) {
- a.setDuration(mDuration);
+ play(as, a, a.getStartDelay(), mDuration);
+ }
+
+ private void play(AnimatorSet as, Animator a, long startDelay, int duration) {
+ a.setStartDelay(startDelay);
+ a.setDuration(duration);
as.play(a);
}
@@ -348,12 +348,6 @@
: ObjectAnimator.ofFloat(view, property, v2, v1);
}
- private Animator getAnimator(List<BubbleTextView> items, Property property, int v1, int v2) {
- return mIsOpening
- ? ObjectAnimator.ofArgb(items, property, v1, v2)
- : ObjectAnimator.ofArgb(items, property, v2, v1);
- }
-
private Animator getAnimator(GradientDrawable drawable, String property, int v1, int v2) {
return mIsOpening
? ObjectAnimator.ofArgb(drawable, property, v1, v2)
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index b793f49..1cc285e 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -19,27 +19,15 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Path;
import android.graphics.Point;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Region;
-import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
-import android.support.v4.graphics.ColorUtils;
+import android.support.annotation.NonNull;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
import android.util.Property;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -58,7 +46,6 @@
import com.android.launcher3.CheckLongPressHelper;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.FolderInfo.FolderListener;
import com.android.launcher3.ItemInfo;
@@ -77,7 +64,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragView;
-import com.android.launcher3.util.Themes;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.widget.PendingAddShortcutInfo;
@@ -101,8 +87,6 @@
private CheckLongPressHelper mLongPressHelper;
private StylusEventHelper mStylusEventHelper;
- // The number of icons to display in the
- private static final int CONSUMPTION_ANIMATION_DURATION = 100;
private static final int DROP_IN_ANIMATION_DURATION = 400;
private static final int INITIAL_ITEM_ANIMATION_DURATION = 350;
private static final int FINAL_ITEM_ANIMATION_DURATION = 200;
@@ -117,11 +101,12 @@
// These variables are all associated with the drawing of the preview; they are stored
// as member variables for shared usage and to avoid computation on each frame
- private int mIntrinsicIconSize = -1;
+ private float mIntrinsicIconSize = -1;
private int mTotalWidth = -1;
private int mPrevTopPadding = -1;
PreviewBackground mBackground = new PreviewBackground();
+ private boolean mBackgroundIsVisible = true;
private PreviewLayoutRule mPreviewLayoutRule;
@@ -132,7 +117,7 @@
FolderIconPreviewVerifier mPreviewVerifier;
private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0);
- private ArrayList<PreviewItemDrawingParams> mDrawingParams = new ArrayList<PreviewItemDrawingParams>();
+ private ArrayList<PreviewItemDrawingParams> mDrawingParams = new ArrayList<>();
private Drawable mReferenceDrawable = null;
private Alarm mOpenAlarm = new Alarm();
@@ -240,8 +225,7 @@
}
public boolean acceptDrop(ItemInfo dragInfo) {
- final ItemInfo item = dragInfo;
- return !mFolder.isDestroyed() && willAcceptItem(item);
+ return !mFolder.isDestroyed() && willAcceptItem(dragInfo);
}
public void addItem(ShortcutInfo item) {
@@ -421,44 +405,19 @@
float newBadgeScale = isBadged ? 1f : 0f;
// Animate when a badge is first added or when it is removed.
if ((wasBadged ^ isBadged) && isShown()) {
- ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, newBadgeScale).start();
+ createBadgeScaleAnimator(newBadgeScale).start();
} else {
mBadgeScale = newBadgeScale;
invalidate();
}
}
- static class PreviewItemDrawingParams {
- PreviewItemDrawingParams(float transX, float transY, float scale, float overlayAlpha) {
- this.transX = transX;
- this.transY = transY;
- this.scale = scale;
- this.overlayAlpha = overlayAlpha;
- }
+ public Animator createBadgeScaleAnimator(float... badgeScales) {
+ return ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, badgeScales);
+ }
- public void update(float transX, float transY, float scale) {
- // We ensure the update will not interfere with an animation on the layout params
- // If the final values differ, we cancel the animation.
- if (anim != null) {
- if (anim.finalTransX == transX || anim.finalTransY == transY
- || anim.finalScale == scale) {
- return;
- }
- anim.cancel();
- }
-
- this.transX = transX;
- this.transY = transY;
- this.scale = scale;
- }
-
- float transX;
- float transY;
- float scale;
- public float overlayAlpha;
- boolean hidden;
- FolderPreviewItemAnim anim;
- Drawable drawable;
+ public boolean hasBadge() {
+ return mBadgeInfo != null && mBadgeInfo.hasBadge();
}
private float getLocalCenterForIndex(int index, int curNumItems, int[] center) {
@@ -470,12 +429,12 @@
float offsetX = mTmpParams.transX + (mTmpParams.scale * mIntrinsicIconSize) / 2;
float offsetY = mTmpParams.transY + (mTmpParams.scale * mIntrinsicIconSize) / 2;
- center[0] = (int) Math.round(offsetX);
- center[1] = (int) Math.round(offsetY);
+ center[0] = Math.round(offsetX);
+ center[1] = Math.round(offsetY);
return mTmpParams.scale;
}
- private PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
+ PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
PreviewItemDrawingParams params) {
// We use an index of -1 to represent an icon on the workspace for the destroy and
// create animations
@@ -502,385 +461,32 @@
Drawable d = params.drawable;
if (d != null) {
- mTempBounds.set(d.getBounds());
- d.setBounds(0, 0, mIntrinsicIconSize, mIntrinsicIconSize);
- if (d instanceof FastBitmapDrawable) {
- FastBitmapDrawable fd = (FastBitmapDrawable) d;
- fd.drawWithBrightness(canvas, params.overlayAlpha);
- } else {
- d.setColorFilter(Color.argb((int) (params.overlayAlpha * 255), 255, 255, 255),
- PorterDuff.Mode.SRC_ATOP);
- d.draw(canvas);
- d.clearColorFilter();
- }
- d.setBounds(mTempBounds);
+ Rect bounds = d.getBounds();
+ canvas.save();
+ canvas.translate(-bounds.left, -bounds.top);
+ canvas.scale(mIntrinsicIconSize / bounds.width(), mIntrinsicIconSize / bounds.height());
+ d.draw(canvas);
+ canvas.restore();
}
canvas.restore();
}
- /**
- * This object represents a FolderIcon preview background. It stores drawing / measurement
- * information, handles drawing, and animation (accept state <--> rest state).
- */
- public static class PreviewBackground {
-
- private final PorterDuffXfermode mClipPorterDuffXfermode
- = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
- // Create a RadialGradient such that it draws a black circle and then extends with
- // transparent. To achieve this, we keep the gradient to black for the range [0, 1) and
- // just at the edge quickly change it to transparent.
- private final RadialGradient mClipShader = new RadialGradient(0, 0, 1,
- new int[] {Color.BLACK, Color.BLACK, Color.TRANSPARENT },
- new float[] {0, 0.999f, 1},
- Shader.TileMode.CLAMP);
-
- private final PorterDuffXfermode mShadowPorterDuffXfermode
- = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
- private RadialGradient mShadowShader = null;
-
- private final Matrix mShaderMatrix = new Matrix();
- private final Path mPath = new Path();
-
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
- private float mScale = 1f;
- private float mColorMultiplier = 1f;
- private int mBgColor;
- private float mStrokeWidth;
- private int mStrokeAlpha = MAX_BG_OPACITY;
- private View mInvalidateDelegate;
-
- public int previewSize;
- private int basePreviewOffsetX;
- private int basePreviewOffsetY;
-
- private CellLayout mDrawingDelegate;
- public int delegateCellX;
- public int delegateCellY;
-
- // When the PreviewBackground is drawn under an icon (for creating a folder) the border
- // should not occlude the icon
- public boolean isClipping = true;
-
- // Drawing / animation configurations
- private static final float ACCEPT_SCALE_FACTOR = 1.25f;
- private static final float ACCEPT_COLOR_MULTIPLIER = 1.5f;
-
- // Expressed on a scale from 0 to 255.
- private static final int BG_OPACITY = 160;
- private static final int MAX_BG_OPACITY = 225;
- private static final int SHADOW_OPACITY = 40;
-
- ValueAnimator mScaleAnimator;
- ObjectAnimator mStrokeAlphaAnimator;
-
- private static final Property<PreviewBackground, Integer> STROKE_ALPHA =
- new Property<PreviewBackground, Integer>(Integer.class, "strokeAlpha") {
- @Override
- public Integer get(PreviewBackground previewBackground) {
- return previewBackground.mStrokeAlpha;
- }
-
- @Override
- public void set(PreviewBackground previewBackground, Integer alpha) {
- previewBackground.mStrokeAlpha = alpha;
- previewBackground.invalidate();
- }
- };
-
- public void setup(Launcher launcher, View invalidateDelegate,
- int availableSpace, int topPadding) {
- mInvalidateDelegate = invalidateDelegate;
- mBgColor = Themes.getAttrColor(launcher, android.R.attr.colorPrimary);
-
- DeviceProfile grid = launcher.getDeviceProfile();
- final int previewSize = grid.folderIconSizePx;
- final int previewPadding = grid.folderIconPreviewPadding;
-
- this.previewSize = (previewSize - 2 * previewPadding);
-
- basePreviewOffsetX = (availableSpace - this.previewSize) / 2;
- basePreviewOffsetY = previewPadding + grid.folderBackgroundOffset + topPadding;
-
- // Stroke width is 1dp
- mStrokeWidth = launcher.getResources().getDisplayMetrics().density;
-
- float radius = getScaledRadius();
- float shadowRadius = radius + mStrokeWidth;
- int shadowColor = Color.argb(SHADOW_OPACITY, 0, 0, 0);
- mShadowShader = new RadialGradient(0, 0, 1,
- new int[] {shadowColor, Color.TRANSPARENT},
- new float[] {radius / shadowRadius, 1},
- Shader.TileMode.CLAMP);
-
- invalidate();
- }
-
- int getRadius() {
- return previewSize / 2;
- }
-
- int getScaledRadius() {
- return (int) (mScale * getRadius());
- }
-
- int getOffsetX() {
- return basePreviewOffsetX - (getScaledRadius() - getRadius());
- }
-
- int getOffsetY() {
- return basePreviewOffsetY - (getScaledRadius() - getRadius());
- }
-
- /**
- * Returns the progress of the scale animation, where 0 means the scale is at 1f
- * and 1 means the scale is at ACCEPT_SCALE_FACTOR.
- */
- float getScaleProgress() {
- return (mScale - 1f) / (ACCEPT_SCALE_FACTOR - 1f);
- }
-
- void invalidate() {
- if (mInvalidateDelegate != null) {
- mInvalidateDelegate.invalidate();
- }
-
- if (mDrawingDelegate != null) {
- mDrawingDelegate.invalidate();
- }
- }
-
- void setInvalidateDelegate(View invalidateDelegate) {
- mInvalidateDelegate = invalidateDelegate;
- invalidate();
- }
-
- public void drawBackground(Canvas canvas) {
- mPaint.setStyle(Paint.Style.FILL);
- int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
- mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, alpha));
-
- drawCircle(canvas, 0 /* deltaRadius */);
-
- // Draw shadow.
- if (mShadowShader == null) {
- return;
- }
- float radius = getScaledRadius();
- float shadowRadius = radius + mStrokeWidth;
- mPaint.setColor(Color.BLACK);
- int offsetX = getOffsetX();
- int offsetY = getOffsetY();
- final int saveCount;
- if (canvas.isHardwareAccelerated()) {
- saveCount = canvas.saveLayer(offsetX - mStrokeWidth, offsetY,
- offsetX + radius + shadowRadius, offsetY + shadowRadius + shadowRadius,
- null, Canvas.CLIP_TO_LAYER_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
-
- } else {
- saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
- clipCanvasSoftware(canvas, Region.Op.DIFFERENCE);
- }
-
- mShaderMatrix.setScale(shadowRadius, shadowRadius);
- mShaderMatrix.postTranslate(radius + offsetX, shadowRadius + offsetY);
- mShadowShader.setLocalMatrix(mShaderMatrix);
- mPaint.setShader(mShadowShader);
- canvas.drawPaint(mPaint);
- mPaint.setShader(null);
-
- if (canvas.isHardwareAccelerated()) {
- mPaint.setXfermode(mShadowPorterDuffXfermode);
- canvas.drawCircle(radius + offsetX, radius + offsetY, radius, mPaint);
- mPaint.setXfermode(null);
- }
-
- canvas.restoreToCount(saveCount);
- }
-
- public void animateBackgroundStroke() {
- if (mStrokeAlphaAnimator != null) {
- mStrokeAlphaAnimator.cancel();
- }
- mStrokeAlphaAnimator = ObjectAnimator
- .ofInt(this, STROKE_ALPHA, MAX_BG_OPACITY / 2, MAX_BG_OPACITY)
- .setDuration(100);
- mStrokeAlphaAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mStrokeAlphaAnimator = null;
- }
- });
- mStrokeAlphaAnimator.start();
- }
-
- public void drawBackgroundStroke(Canvas canvas) {
- mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, mStrokeAlpha));
- mPaint.setStyle(Paint.Style.STROKE);
- mPaint.setStrokeWidth(mStrokeWidth);
- drawCircle(canvas, 1 /* deltaRadius */);
- }
-
- public void drawLeaveBehind(Canvas canvas) {
- float originalScale = mScale;
- mScale = 0.5f;
-
- mPaint.setStyle(Paint.Style.FILL);
- mPaint.setColor(Color.argb(160, 245, 245, 245));
- drawCircle(canvas, 0 /* deltaRadius */);
-
- mScale = originalScale;
- }
-
- private void drawCircle(Canvas canvas,float deltaRadius) {
- float radius = getScaledRadius();
- canvas.drawCircle(radius + getOffsetX(), radius + getOffsetY(),
- radius - deltaRadius, mPaint);
- }
-
- // It is the callers responsibility to save and restore the canvas layers.
- private void clipCanvasSoftware(Canvas canvas, Region.Op op) {
- mPath.reset();
- float r = getScaledRadius();
- mPath.addCircle(r + getOffsetX(), r + getOffsetY(), r, Path.Direction.CW);
- canvas.clipPath(mPath, op);
- }
-
- // It is the callers responsibility to save and restore the canvas layers.
- private void clipCanvasHardware(Canvas canvas) {
- mPaint.setColor(Color.BLACK);
- mPaint.setXfermode(mClipPorterDuffXfermode);
-
- float radius = getScaledRadius();
- mShaderMatrix.setScale(radius, radius);
- mShaderMatrix.postTranslate(radius + getOffsetX(), radius + getOffsetY());
- mClipShader.setLocalMatrix(mShaderMatrix);
- mPaint.setShader(mClipShader);
- canvas.drawPaint(mPaint);
- mPaint.setXfermode(null);
- mPaint.setShader(null);
- }
-
- private void delegateDrawing(CellLayout delegate, int cellX, int cellY) {
- if (mDrawingDelegate != delegate) {
- delegate.addFolderBackground(this);
- }
-
- mDrawingDelegate = delegate;
- delegateCellX = cellX;
- delegateCellY = cellY;
-
- invalidate();
- }
-
- private void clearDrawingDelegate() {
- if (mDrawingDelegate != null) {
- mDrawingDelegate.removeFolderBackground(this);
- }
-
- mDrawingDelegate = null;
- invalidate();
- }
-
- private boolean drawingDelegated() {
- return mDrawingDelegate != null;
- }
-
- private void animateScale(float finalScale, float finalMultiplier,
- final Runnable onStart, final Runnable onEnd) {
- final float scale0 = mScale;
- final float scale1 = finalScale;
-
- final float bgMultiplier0 = mColorMultiplier;
- final float bgMultiplier1 = finalMultiplier;
-
- if (mScaleAnimator != null) {
- mScaleAnimator.cancel();
- }
-
- mScaleAnimator = LauncherAnimUtils.ofFloat(0f, 1.0f);
-
- mScaleAnimator.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float prog = animation.getAnimatedFraction();
- mScale = prog * scale1 + (1 - prog) * scale0;
- mColorMultiplier = prog * bgMultiplier1 + (1 - prog) * bgMultiplier0;
- invalidate();
- }
- });
- mScaleAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- if (onStart != null) {
- onStart.run();
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (onEnd != null) {
- onEnd.run();
- }
- mScaleAnimator = null;
- }
- });
-
- mScaleAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION);
- mScaleAnimator.start();
- }
-
- public void animateToAccept(final CellLayout cl, final int cellX, final int cellY) {
- Runnable onStart = new Runnable() {
- @Override
- public void run() {
- delegateDrawing(cl, cellX, cellY);
- }
- };
- animateScale(ACCEPT_SCALE_FACTOR, ACCEPT_COLOR_MULTIPLIER, onStart, null);
- }
-
- public void animateToRest() {
- // This can be called multiple times -- we need to make sure the drawing delegate
- // is saved and restored at the beginning of the animation, since cancelling the
- // existing animation can clear the delgate.
- final CellLayout cl = mDrawingDelegate;
- final int cellX = delegateCellX;
- final int cellY = delegateCellY;
-
- Runnable onStart = new Runnable() {
- @Override
- public void run() {
- delegateDrawing(cl, cellX, cellY);
- }
- };
- Runnable onEnd = new Runnable() {
- @Override
- public void run() {
- clearDrawingDelegate();
- }
- };
- animateScale(1f, 1f, onStart, onEnd);
- }
-
- public int getBackgroundAlpha() {
- return (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
- }
-
- public float getStrokeWidth() {
- return mStrokeWidth;
- }
- }
-
public void setFolderBackground(PreviewBackground bg) {
mBackground = bg;
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);
}
@@ -940,89 +546,14 @@
}
}
- class FolderPreviewItemAnim {
- ValueAnimator mValueAnimator;
- float finalScale;
- float finalTransX;
- float finalTransY;
-
- /**
- *
- * @param params layout params to animate
- * @param index0 original index of the item to be animated
- * @param nItems0 original number of items in the preview
- * @param index1 new index of the item to be animated
- * @param nItems1 new number of items in the preview
- * @param duration duration in ms of the animation
- * @param onCompleteRunnable runnable to execute upon animation completion
- */
- public FolderPreviewItemAnim(final PreviewItemDrawingParams params, int index0, int nItems0,
- int index1, int nItems1, int duration, final Runnable onCompleteRunnable) {
-
- computePreviewItemDrawingParams(index1, nItems1, mTmpParams);
-
- finalScale = mTmpParams.scale;
- finalTransX = mTmpParams.transX;
- finalTransY = mTmpParams.transY;
-
- computePreviewItemDrawingParams(index0, nItems0, mTmpParams);
-
- final float scale0 = mTmpParams.scale;
- final float transX0 = mTmpParams.transX;
- final float transY0 = mTmpParams.transY;
-
- mValueAnimator = LauncherAnimUtils.ofFloat(0f, 1.0f);
- mValueAnimator.addUpdateListener(new AnimatorUpdateListener(){
- public void onAnimationUpdate(ValueAnimator animation) {
- float progress = animation.getAnimatedFraction();
-
- params.transX = transX0 + progress * (finalTransX - transX0);
- params.transY = transY0 + progress * (finalTransY - transY0);
- params.scale = scale0 + progress * (finalScale - scale0);
- invalidate();
- }
- });
-
- mValueAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (onCompleteRunnable != null) {
- onCompleteRunnable.run();
- }
- params.anim = null;
- }
- });
- mValueAnimator.setDuration(duration);
- }
-
- public void start() {
- mValueAnimator.start();
- }
-
- public void cancel() {
- mValueAnimator.cancel();
- }
-
- public boolean hasEqualFinalState(FolderPreviewItemAnim anim) {
- return finalTransY == anim.finalTransY && finalTransX == anim.finalTransX &&
- finalScale == anim.finalScale;
-
- }
- }
-
private void animateFirstItem(final Drawable d, int duration, final boolean reverse,
final Runnable onCompleteRunnable) {
-
FolderPreviewItemAnim anim;
if (!reverse) {
- anim = new FolderPreviewItemAnim(mDrawingParams.get(0), -1, -1, 0, 2, duration,
+ anim = new FolderPreviewItemAnim(this, mDrawingParams.get(0), -1, -1, 0, 2, duration,
onCompleteRunnable);
} else {
- anim = new FolderPreviewItemAnim(mDrawingParams.get(0), 0, 2, -1, -1, duration,
+ anim = new FolderPreviewItemAnim(this, mDrawingParams.get(0), 0, 2, -1, -1, duration,
onCompleteRunnable);
}
anim.start();
@@ -1058,6 +589,16 @@
return itemsToDisplay;
}
+ @Override
+ protected boolean verifyDrawable(@NonNull Drawable who) {
+ for (int i = 0; i < mDrawingParams.size(); i++) {
+ if (mDrawingParams.get(i).drawable == who) {
+ return true;
+ }
+ }
+ return super.verifyDrawable(who);
+ }
+
private void updateItemDrawingParams(boolean animate) {
List<BubbleTextView> items = getItemsToDisplay();
int nItemsInPreview = items.size();
@@ -1076,13 +617,19 @@
PreviewItemDrawingParams p = mDrawingParams.get(i);
p.drawable = items.get(i).getCompoundDrawables()[1];
+ if (p.drawable != null && !mFolder.isOpen()) {
+ // Set the callback to FolderIcon as it is responsible to drawing the icon. The
+ // callback will be release when the folder is opened.
+ p.drawable.setCallback(this);
+ }
+
if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) {
computePreviewItemDrawingParams(i, nItemsInPreview, p);
if (mReferenceDrawable == null) {
mReferenceDrawable = p.drawable;
}
} else {
- FolderPreviewItemAnim anim = new FolderPreviewItemAnim(p, i, prevNumItems, i,
+ FolderPreviewItemAnim anim = new FolderPreviewItemAnim(this, p, i, prevNumItems, i,
nItemsInPreview, DROP_IN_ANIMATION_DURATION, null);
if (p.anim != null) {
@@ -1243,10 +790,10 @@
}
}
- public interface PreviewLayoutRule {
+ interface PreviewLayoutRule {
PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
PreviewItemDrawingParams params);
- void init(int availableSpace, int intrinsicIconSize, boolean rtl);
+ void init(int availableSpace, float intrinsicIconSize, boolean rtl);
float scaleForItem(int index, int totalNumItems);
float getIconSize();
int maxNumItems();
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index 19a16b1..d0ac9f4 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,6 +19,8 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
@@ -46,7 +48,6 @@
import com.android.launcher3.util.Thunk;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -72,7 +73,7 @@
private final LayoutInflater mInflater;
private final ViewGroupFocusHelper mFocusIndicatorHelper;
- @Thunk final HashMap<View, Runnable> mPendingAnimations = new HashMap<>();
+ @Thunk final ArrayMap<View, Runnable> mPendingAnimations = new ArrayMap<>();
@ViewDebug.ExportedProperty(category = "launcher")
private final int mMaxCountX;
@@ -111,7 +112,7 @@
public void setFolder(Folder folder) {
mFolder = folder;
mKeyListener = new PagedFolderKeyEventListener(folder);
- mPageIndicator = (PageIndicator) folder.findViewById(R.id.folder_page_indicator);
+ mPageIndicator = folder.findViewById(R.id.folder_page_indicator);
initParentViews(folder);
}
@@ -185,8 +186,8 @@
* @return list of items that could not be bound, probably because we hit the max size limit.
*/
public ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> items) {
- ArrayList<View> icons = new ArrayList<View>();
- ArrayList<ShortcutInfo> extra = new ArrayList<ShortcutInfo>();
+ ArrayList<View> icons = new ArrayList<>();
+ ArrayList<ShortcutInfo> extra = new ArrayList<>();
for (ShortcutInfo item : items) {
if (!ALLOW_FOLDER_SCROLL && icons.size() >= mMaxItemsPerPage) {
@@ -247,6 +248,7 @@
final BubbleTextView textView = (BubbleTextView) mInflater.inflate(
R.layout.folder_application, null, false);
textView.applyFromShortcutInfo(item);
+ textView.setHapticFeedbackEnabled(false);
textView.setOnClickListener(mFolder);
textView.setOnLongClickListener(mFolder);
textView.setOnFocusChangeListener(mFocusIndicatorHelper);
@@ -319,7 +321,7 @@
@SuppressLint("RtlHardcoded")
private void arrangeChildren(ArrayList<View> list, int itemCount, boolean saveChanges) {
- ArrayList<CellLayout> pages = new ArrayList<CellLayout>();
+ ArrayList<CellLayout> pages = new ArrayList<>();
for (int i = 0; i < getChildCount(); i++) {
CellLayout page = (CellLayout) getChildAt(i);
page.removeAllViews();
@@ -526,7 +528,7 @@
*/
public void completePendingPageChanges() {
if (!mPendingAnimations.isEmpty()) {
- HashMap<View, Runnable> pendingViews = new HashMap<>(mPendingAnimations);
+ ArrayMap<View, Runnable> pendingViews = new ArrayMap<>(mPendingAnimations);
for (Map.Entry<View, Runnable> e : pendingViews.entrySet()) {
e.getKey().animate().cancel();
e.getValue().run();
@@ -555,7 +557,14 @@
if (page != null) {
ShortcutAndWidgetContainer parent = page.getShortcutsAndWidgets();
for (int i = parent.getChildCount() - 1; i >= 0; i--) {
- ((BubbleTextView) parent.getChildAt(i)).verifyHighRes();
+ BubbleTextView icon = ((BubbleTextView) parent.getChildAt(i));
+ icon.verifyHighRes();
+ // Set the callback back to the actual icon, in case
+ // it was captured by the FolderIcon
+ Drawable d = icon.getCompoundDrawables()[1];
+ if (d != null) {
+ d.setCallback(icon);
+ }
}
}
}
diff --git a/src/com/android/launcher3/folder/FolderPreviewItemAnim.java b/src/com/android/launcher3/folder/FolderPreviewItemAnim.java
new file mode 100644
index 0000000..0da7c5c
--- /dev/null
+++ b/src/com/android/launcher3/folder/FolderPreviewItemAnim.java
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+package com.android.launcher3.folder;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+
+import com.android.launcher3.LauncherAnimUtils;
+
+/**
+ * Animates a Folder preview item.
+ */
+class FolderPreviewItemAnim {
+ private ValueAnimator mValueAnimator;
+
+ float finalScale;
+ float finalTransX;
+ float finalTransY;
+
+ private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0);
+
+ /**
+ * @param folderIcon The FolderIcon this preview will be drawn in.
+ * @param params layout params to animate
+ * @param index0 original index of the item to be animated
+ * @param items0 original number of items in the preview
+ * @param index1 new index of the item to be animated
+ * @param items1 new number of items in the preview
+ * @param duration duration in ms of the animation
+ * @param onCompleteRunnable runnable to execute upon animation completion
+ */
+ FolderPreviewItemAnim(final FolderIcon folderIcon, final PreviewItemDrawingParams params,
+ int index0, int items0, int index1, int items1, int duration,
+ final Runnable onCompleteRunnable) {
+ folderIcon.computePreviewItemDrawingParams(index1, items1, mTmpParams);
+
+ finalScale = mTmpParams.scale;
+ finalTransX = mTmpParams.transX;
+ finalTransY = mTmpParams.transY;
+
+ folderIcon.computePreviewItemDrawingParams(index0, items0, mTmpParams);
+
+ final float scale0 = mTmpParams.scale;
+ final float transX0 = mTmpParams.transX;
+ final float transY0 = mTmpParams.transY;
+
+ mValueAnimator = LauncherAnimUtils.ofFloat(0f, 1.0f);
+ mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float progress = animation.getAnimatedFraction();
+
+ params.transX = transX0 + progress * (finalTransX - transX0);
+ params.transY = transY0 + progress * (finalTransY - transY0);
+ params.scale = scale0 + progress * (finalScale - scale0);
+ folderIcon.invalidate();
+ }
+ });
+ mValueAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (onCompleteRunnable != null) {
+ onCompleteRunnable.run();
+ }
+ params.anim = null;
+ }
+ });
+ mValueAnimator.setDuration(duration);
+ }
+
+ public void start() {
+ mValueAnimator.start();
+ }
+
+ public void cancel() {
+ mValueAnimator.cancel();
+ }
+
+ public boolean hasEqualFinalState(FolderPreviewItemAnim anim) {
+ return finalTransY == anim.finalTransY && finalTransX == anim.finalTransX &&
+ finalScale == anim.finalScale;
+
+ }
+}
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
new file mode 100644
index 0000000..44ebbcd
--- /dev/null
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -0,0 +1,430 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.folder;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RadialGradient;
+import android.graphics.Region;
+import android.graphics.Shader;
+import android.support.v4.graphics.ColorUtils;
+import android.util.Property;
+import android.view.View;
+
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.util.Themes;
+
+/**
+ * This object represents a FolderIcon preview background. It stores drawing / measurement
+ * information, handles drawing, and animation (accept state <--> rest state).
+ */
+public class PreviewBackground {
+
+ private static final int CONSUMPTION_ANIMATION_DURATION = 100;
+
+ private final PorterDuffXfermode mClipPorterDuffXfermode
+ = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
+ // Create a RadialGradient such that it draws a black circle and then extends with
+ // transparent. To achieve this, we keep the gradient to black for the range [0, 1) and
+ // just at the edge quickly change it to transparent.
+ private final RadialGradient mClipShader = new RadialGradient(0, 0, 1,
+ new int[] {Color.BLACK, Color.BLACK, Color.TRANSPARENT },
+ new float[] {0, 0.999f, 1},
+ Shader.TileMode.CLAMP);
+
+ private final PorterDuffXfermode mShadowPorterDuffXfermode
+ = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
+ private RadialGradient mShadowShader = null;
+
+ private final Matrix mShaderMatrix = new Matrix();
+ private final Path mPath = new Path();
+
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ float mScale = 1f;
+ private float mColorMultiplier = 1f;
+ private int mBgColor;
+ private float mStrokeWidth;
+ private int mStrokeAlpha = MAX_BG_OPACITY;
+ private int mShadowAlpha = 255;
+ private View mInvalidateDelegate;
+
+ int previewSize;
+ int basePreviewOffsetX;
+ int basePreviewOffsetY;
+
+ private CellLayout mDrawingDelegate;
+ public int delegateCellX;
+ public int delegateCellY;
+
+ // When the PreviewBackground is drawn under an icon (for creating a folder) the border
+ // should not occlude the icon
+ public boolean isClipping = true;
+
+ // Drawing / animation configurations
+ private static final float ACCEPT_SCALE_FACTOR = 1.25f;
+ private static final float ACCEPT_COLOR_MULTIPLIER = 1.5f;
+
+ // Expressed on a scale from 0 to 255.
+ private static final int BG_OPACITY = 160;
+ private static final int MAX_BG_OPACITY = 225;
+ private static final int SHADOW_OPACITY = 40;
+
+ private ValueAnimator mScaleAnimator;
+ private ObjectAnimator mStrokeAlphaAnimator;
+ private ObjectAnimator mShadowAnimator;
+
+ private static final Property<PreviewBackground, Integer> STROKE_ALPHA =
+ new Property<PreviewBackground, Integer>(Integer.class, "strokeAlpha") {
+ @Override
+ public Integer get(PreviewBackground previewBackground) {
+ return previewBackground.mStrokeAlpha;
+ }
+
+ @Override
+ public void set(PreviewBackground previewBackground, Integer alpha) {
+ previewBackground.mStrokeAlpha = alpha;
+ previewBackground.invalidate();
+ }
+ };
+
+ private static final Property<PreviewBackground, Integer> SHADOW_ALPHA =
+ new Property<PreviewBackground, Integer>(Integer.class, "shadowAlpha") {
+ @Override
+ public Integer get(PreviewBackground previewBackground) {
+ return previewBackground.mShadowAlpha;
+ }
+
+ @Override
+ public void set(PreviewBackground previewBackground, Integer alpha) {
+ previewBackground.mShadowAlpha = alpha;
+ previewBackground.invalidate();
+ }
+ };
+
+ public void setup(Launcher launcher, View invalidateDelegate,
+ int availableSpace, int topPadding) {
+ mInvalidateDelegate = invalidateDelegate;
+ mBgColor = Themes.getAttrColor(launcher, android.R.attr.colorPrimary);
+
+ DeviceProfile grid = launcher.getDeviceProfile();
+ final int previewSize = grid.folderIconSizePx;
+ final int previewPadding = grid.folderIconPreviewPadding;
+
+ this.previewSize = (previewSize - 2 * previewPadding);
+
+ basePreviewOffsetX = (availableSpace - this.previewSize) / 2;
+ basePreviewOffsetY = previewPadding + grid.folderBackgroundOffset + topPadding;
+
+ // Stroke width is 1dp
+ mStrokeWidth = launcher.getResources().getDisplayMetrics().density;
+
+ float radius = getScaledRadius();
+ float shadowRadius = radius + mStrokeWidth;
+ int shadowColor = Color.argb(SHADOW_OPACITY, 0, 0, 0);
+ mShadowShader = new RadialGradient(0, 0, 1,
+ new int[] {shadowColor, Color.TRANSPARENT},
+ new float[] {radius / shadowRadius, 1},
+ Shader.TileMode.CLAMP);
+
+ invalidate();
+ }
+
+ int getRadius() {
+ return previewSize / 2;
+ }
+
+ int getScaledRadius() {
+ return (int) (mScale * getRadius());
+ }
+
+ int getOffsetX() {
+ return basePreviewOffsetX - (getScaledRadius() - getRadius());
+ }
+
+ int getOffsetY() {
+ return basePreviewOffsetY - (getScaledRadius() - getRadius());
+ }
+
+ /**
+ * Returns the progress of the scale animation, where 0 means the scale is at 1f
+ * and 1 means the scale is at ACCEPT_SCALE_FACTOR.
+ */
+ float getScaleProgress() {
+ return (mScale - 1f) / (ACCEPT_SCALE_FACTOR - 1f);
+ }
+
+ void invalidate() {
+ if (mInvalidateDelegate != null) {
+ mInvalidateDelegate.invalidate();
+ }
+
+ if (mDrawingDelegate != null) {
+ mDrawingDelegate.invalidate();
+ }
+ }
+
+ void setInvalidateDelegate(View invalidateDelegate) {
+ mInvalidateDelegate = invalidateDelegate;
+ invalidate();
+ }
+
+ public void drawBackground(Canvas canvas) {
+ mPaint.setStyle(Paint.Style.FILL);
+ int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
+ mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, alpha));
+
+ drawCircle(canvas, 0 /* deltaRadius */);
+
+ // Draw shadow.
+ if (mShadowShader == null) {
+ return;
+ }
+ float radius = getScaledRadius();
+ float shadowRadius = radius + mStrokeWidth;
+ mPaint.setColor(Color.BLACK);
+ int offsetX = getOffsetX();
+ int offsetY = getOffsetY();
+ final int saveCount;
+ if (canvas.isHardwareAccelerated()) {
+ saveCount = canvas.saveLayer(offsetX - mStrokeWidth, offsetY,
+ offsetX + radius + shadowRadius, offsetY + shadowRadius + shadowRadius,
+ null, Canvas.CLIP_TO_LAYER_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
+
+ } else {
+ saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
+ clipCanvasSoftware(canvas, Region.Op.DIFFERENCE);
+ }
+
+ mShaderMatrix.setScale(shadowRadius, shadowRadius);
+ mShaderMatrix.postTranslate(radius + offsetX, shadowRadius + offsetY);
+ mShadowShader.setLocalMatrix(mShaderMatrix);
+ mPaint.setAlpha(mShadowAlpha);
+ mPaint.setShader(mShadowShader);
+ canvas.drawPaint(mPaint);
+ mPaint.setAlpha(255);
+ mPaint.setShader(null);
+ if (canvas.isHardwareAccelerated()) {
+ mPaint.setXfermode(mShadowPorterDuffXfermode);
+ canvas.drawCircle(radius + offsetX, radius + offsetY, radius, mPaint);
+ mPaint.setXfermode(null);
+ }
+
+ canvas.restoreToCount(saveCount);
+ }
+
+ public void fadeInBackgroundShadow() {
+ if (mShadowAnimator != null) {
+ mShadowAnimator.cancel();
+ }
+ mShadowAnimator = ObjectAnimator
+ .ofInt(this, SHADOW_ALPHA, 0, 255)
+ .setDuration(100);
+ mShadowAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mShadowAnimator = null;
+ }
+ });
+ mShadowAnimator.start();
+ }
+
+ public void animateBackgroundStroke() {
+ if (mStrokeAlphaAnimator != null) {
+ mStrokeAlphaAnimator.cancel();
+ }
+ mStrokeAlphaAnimator = ObjectAnimator
+ .ofInt(this, STROKE_ALPHA, MAX_BG_OPACITY / 2, MAX_BG_OPACITY)
+ .setDuration(100);
+ mStrokeAlphaAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mStrokeAlphaAnimator = null;
+ }
+ });
+ mStrokeAlphaAnimator.start();
+ }
+
+ public void drawBackgroundStroke(Canvas canvas) {
+ mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, mStrokeAlpha));
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setStrokeWidth(mStrokeWidth);
+ drawCircle(canvas, 1 /* deltaRadius */);
+ }
+
+ public void drawLeaveBehind(Canvas canvas) {
+ float originalScale = mScale;
+ mScale = 0.5f;
+
+ mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setColor(Color.argb(160, 245, 245, 245));
+ drawCircle(canvas, 0 /* deltaRadius */);
+
+ mScale = originalScale;
+ }
+
+ private void drawCircle(Canvas canvas,float deltaRadius) {
+ float radius = getScaledRadius();
+ canvas.drawCircle(radius + getOffsetX(), radius + getOffsetY(),
+ radius - deltaRadius, mPaint);
+ }
+
+ // It is the callers responsibility to save and restore the canvas layers.
+ void clipCanvasSoftware(Canvas canvas, Region.Op op) {
+ mPath.reset();
+ float r = getScaledRadius();
+ mPath.addCircle(r + getOffsetX(), r + getOffsetY(), r, Path.Direction.CW);
+ canvas.clipPath(mPath, op);
+ }
+
+ // It is the callers responsibility to save and restore the canvas layers.
+ void clipCanvasHardware(Canvas canvas) {
+ mPaint.setColor(Color.BLACK);
+ mPaint.setXfermode(mClipPorterDuffXfermode);
+
+ float radius = getScaledRadius();
+ mShaderMatrix.setScale(radius, radius);
+ mShaderMatrix.postTranslate(radius + getOffsetX(), radius + getOffsetY());
+ mClipShader.setLocalMatrix(mShaderMatrix);
+ mPaint.setShader(mClipShader);
+ canvas.drawPaint(mPaint);
+ mPaint.setXfermode(null);
+ mPaint.setShader(null);
+ }
+
+ private void delegateDrawing(CellLayout delegate, int cellX, int cellY) {
+ if (mDrawingDelegate != delegate) {
+ delegate.addFolderBackground(this);
+ }
+
+ mDrawingDelegate = delegate;
+ delegateCellX = cellX;
+ delegateCellY = cellY;
+
+ invalidate();
+ }
+
+ private void clearDrawingDelegate() {
+ if (mDrawingDelegate != null) {
+ mDrawingDelegate.removeFolderBackground(this);
+ }
+
+ mDrawingDelegate = null;
+ invalidate();
+ }
+
+ boolean drawingDelegated() {
+ return mDrawingDelegate != null;
+ }
+
+ private void animateScale(float finalScale, float finalMultiplier,
+ final Runnable onStart, final Runnable onEnd) {
+ final float scale0 = mScale;
+ final float scale1 = finalScale;
+
+ final float bgMultiplier0 = mColorMultiplier;
+ final float bgMultiplier1 = finalMultiplier;
+
+ if (mScaleAnimator != null) {
+ mScaleAnimator.cancel();
+ }
+
+ mScaleAnimator = LauncherAnimUtils.ofFloat(0f, 1.0f);
+
+ mScaleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float prog = animation.getAnimatedFraction();
+ mScale = prog * scale1 + (1 - prog) * scale0;
+ mColorMultiplier = prog * bgMultiplier1 + (1 - prog) * bgMultiplier0;
+ invalidate();
+ }
+ });
+ mScaleAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (onStart != null) {
+ onStart.run();
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (onEnd != null) {
+ onEnd.run();
+ }
+ mScaleAnimator = null;
+ }
+ });
+
+ mScaleAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION);
+ mScaleAnimator.start();
+ }
+
+ public void animateToAccept(final CellLayout cl, final int cellX, final int cellY) {
+ Runnable onStart = new Runnable() {
+ @Override
+ public void run() {
+ delegateDrawing(cl, cellX, cellY);
+ }
+ };
+ animateScale(ACCEPT_SCALE_FACTOR, ACCEPT_COLOR_MULTIPLIER, onStart, null);
+ }
+
+ public void animateToRest() {
+ // This can be called multiple times -- we need to make sure the drawing delegate
+ // is saved and restored at the beginning of the animation, since cancelling the
+ // existing animation can clear the delgate.
+ final CellLayout cl = mDrawingDelegate;
+ final int cellX = delegateCellX;
+ final int cellY = delegateCellY;
+
+ Runnable onStart = new Runnable() {
+ @Override
+ public void run() {
+ delegateDrawing(cl, cellX, cellY);
+ }
+ };
+ Runnable onEnd = new Runnable() {
+ @Override
+ public void run() {
+ clearDrawingDelegate();
+ }
+ };
+ animateScale(1f, 1f, onStart, onEnd);
+ }
+
+ public int getBackgroundAlpha() {
+ return (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
+ }
+
+ public float getStrokeWidth() {
+ return mStrokeWidth;
+ }
+}
diff --git a/src/com/android/launcher3/folder/PreviewItemDrawingParams.java b/src/com/android/launcher3/folder/PreviewItemDrawingParams.java
new file mode 100644
index 0000000..607b7ca
--- /dev/null
+++ b/src/com/android/launcher3/folder/PreviewItemDrawingParams.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+package com.android.launcher3.folder;
+
+import android.graphics.drawable.Drawable;
+
+/**
+ * Manages the parameters used to draw a Folder preview item.
+ */
+class PreviewItemDrawingParams {
+ float transX;
+ float transY;
+ float scale;
+ float overlayAlpha;
+ FolderPreviewItemAnim anim;
+ public boolean hidden;
+ Drawable drawable;
+
+ PreviewItemDrawingParams(float transX, float transY, float scale, float overlayAlpha) {
+ this.transX = transX;
+ this.transY = transY;
+ this.scale = scale;
+ this.overlayAlpha = overlayAlpha;
+ }
+
+ public void update(float transX, float transY, float scale) {
+ // We ensure the update will not interfere with an animation on the layout params
+ // If the final values differ, we cancel the animation.
+ if (anim != null) {
+ if (anim.finalTransX == transX || anim.finalTransY == transY
+ || anim.finalScale == scale) {
+ return;
+ }
+ anim.cancel();
+ }
+
+ this.transX = transX;
+ this.transY = transY;
+ this.scale = scale;
+ }
+}
diff --git a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
index 12bca5f..138dc1c 100644
--- a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
@@ -16,8 +16,6 @@
package com.android.launcher3.folder;
-import com.android.launcher3.folder.FolderIcon.PreviewItemDrawingParams;
-
public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
static final int MAX_NUM_ITEMS_IN_PREVIEW = 3;
@@ -35,7 +33,7 @@
private float mMaxPerspectiveShift;
@Override
- public void init(int availableSpace, int intrinsicIconSize, boolean rtl) {
+ public void init(int availableSpace, float intrinsicIconSize, boolean rtl) {
mAvailableSpaceInPreview = availableSpace;
// cos(45) = 0.707 + ~= 0.1) = 0.8f
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index 492d853..10e91c0 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -23,12 +23,11 @@
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.view.View;
-import android.widget.TextView;
+import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetHostView;
import com.android.launcher3.R;
-import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
@@ -57,8 +56,8 @@
blurSizeOutline =
context.getResources().getDimensionPixelSize(R.dimen.blur_size_medium_outline);
- if (mView instanceof TextView) {
- Drawable d = Workspace.getTextViewIcon((TextView) mView);
+ if (mView instanceof BubbleTextView) {
+ Drawable d = ((BubbleTextView) mView).getIcon();
Rect bounds = getDrawableBounds(d);
previewPadding = blurSizeOutline - bounds.left - bounds.top;
} else {
@@ -71,8 +70,8 @@
*/
private void drawDragView(Canvas destCanvas) {
destCanvas.save();
- if (mView instanceof TextView) {
- Drawable d = Workspace.getTextViewIcon((TextView) mView);
+ if (mView instanceof BubbleTextView) {
+ Drawable d = ((BubbleTextView) mView).getIcon();
Rect bounds = getDrawableBounds(d);
destCanvas.translate(blurSizeOutline / 2 - bounds.left,
blurSizeOutline / 2 - bounds.top);
@@ -112,8 +111,8 @@
int width = mView.getWidth();
int height = mView.getHeight();
- if (mView instanceof TextView) {
- Drawable d = Workspace.getTextViewIcon((TextView) mView);
+ if (mView instanceof BubbleTextView) {
+ Drawable d = ((BubbleTextView) mView).getIcon();
Rect bounds = getDrawableBounds(d);
width = bounds.width();
height = bounds.height();
diff --git a/src/com/android/launcher3/graphics/FastScrollThumbDrawable.java b/src/com/android/launcher3/graphics/FastScrollThumbDrawable.java
new file mode 100644
index 0000000..6ebc74e
--- /dev/null
+++ b/src/com/android/launcher3/graphics/FastScrollThumbDrawable.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.graphics;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+
+public class FastScrollThumbDrawable extends Drawable {
+
+ private static final Matrix sMatrix = new Matrix();
+
+ private final Path mPath = new Path();
+ private final Paint mPaint;
+ private final boolean mIsRtl;
+
+ public FastScrollThumbDrawable(Paint paint, boolean isRtl) {
+ mPaint = paint;
+ mIsRtl = isRtl;
+ }
+
+ @Override
+ public void getOutline(Outline outline) {
+ if (mPath.isConvex()) {
+ outline.setConvexPath(mPath);
+ }
+ }
+
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ mPath.reset();
+
+ float r = bounds.height() * 0.5f;
+ // The path represents a rotate tear-drop shape, with radius of one corner is 1/5th of the
+ // other 3 corners.
+ float diameter = 2 * r;
+ float r2 = r / 5;
+ mPath.addRoundRect(bounds.left, bounds.top, bounds.left + diameter, bounds.top + diameter,
+ new float[] {r, r, r, r, r2, r2, r, r},
+ Path.Direction.CCW);
+
+ sMatrix.setRotate(-45, bounds.left + r, bounds.top + r);
+ if (mIsRtl) {
+ sMatrix.postTranslate(bounds.width(), 0);
+ sMatrix.postScale(-1, 1, bounds.width(), 0);
+ }
+ mPath.transform(sMatrix);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.drawPath(mPath, mPaint);
+ }
+
+ @Override
+ public void setAlpha(int i) {
+ // Not supported
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ // Not supported
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+}
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 19e57024..830ca82 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -322,14 +322,16 @@
IconCache cache = app.getIconCache();
Bitmap unbadgedBitmap = unbadgedDrawable == null
? cache.getDefaultIcon(Process.myUserHandle())
- : LauncherIcons.createScaledBitmapWithoutShadow(unbadgedDrawable, context,
- Build.VERSION_CODES.O);
+ : LauncherIcons.createScaledBitmapWithoutShadow(unbadgedDrawable, context, 0);
if (!badged) {
return unbadgedBitmap;
}
unbadgedBitmap = LauncherIcons.addShadowToIcon(unbadgedBitmap, context);
+ return badgeWithBitmap(unbadgedBitmap, getShortcutInfoBadge(shortcutInfo, cache), context);
+ }
+ public static Bitmap getShortcutInfoBadge(ShortcutInfoCompat shortcutInfo, IconCache cache) {
final Bitmap badgeBitmap;
ComponentName cn = shortcutInfo.getActivity();
if (cn != null) {
@@ -347,7 +349,7 @@
cache.getTitleAndIconForApp(pkgInfo, false);
badgeBitmap = pkgInfo.iconBitmap;
}
- return badgeWithBitmap(unbadgedBitmap, badgeBitmap, context);
+ return badgeBitmap;
}
/**
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index 22ce098..06dc7ac 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -69,7 +69,7 @@
private static final int COLOR_TRACK = 0x77EEEEEE;
private static final int COLOR_SHADOW = 0x55000000;
- private static final float SMALL_SCALE = 0.75f;
+ private static final float SMALL_SCALE = 0.6f;
private static final SparseArray<WeakReference<Bitmap>> sShadowCache = new SparseArray<>();
@@ -121,11 +121,11 @@
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mTmpMatrix.setScale(
- (bounds.width() - PROGRESS_WIDTH - 2 * PROGRESS_GAP) / PATH_SIZE,
- (bounds.height() - PROGRESS_WIDTH - 2 * PROGRESS_GAP) / PATH_SIZE);
+ (bounds.width() - 2 * PROGRESS_WIDTH - 2 * PROGRESS_GAP) / PATH_SIZE,
+ (bounds.height() - 2 * PROGRESS_WIDTH - 2 * PROGRESS_GAP) / PATH_SIZE);
mTmpMatrix.postTranslate(
- bounds.left + PROGRESS_WIDTH / 2 + PROGRESS_GAP,
- bounds.top + PROGRESS_WIDTH / 2 + PROGRESS_GAP);
+ bounds.left + PROGRESS_WIDTH + PROGRESS_GAP,
+ bounds.top + PROGRESS_WIDTH + PROGRESS_GAP);
mProgressPath.transform(mTmpMatrix, mScaledTrackPath);
float scale = bounds.width() / PATH_SIZE;
@@ -178,7 +178,7 @@
Rect bounds = getBounds();
canvas.scale(mIconScale, mIconScale, bounds.exactCenterX(), bounds.exactCenterY());
- drawInternal(canvas);
+ super.draw(canvas);
canvas.restoreToCount(saveCount);
}
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/graphics/ShadowGenerator.java b/src/com/android/launcher3/graphics/ShadowGenerator.java
index 9ea11a7..fffea8e 100644
--- a/src/com/android/launcher3/graphics/ShadowGenerator.java
+++ b/src/com/android/launcher3/graphics/ShadowGenerator.java
@@ -28,7 +28,6 @@
import android.support.v4.graphics.ColorUtils;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.util.Preconditions;
/**
* Utility class to add shadows to bitmaps.
@@ -85,48 +84,10 @@
return result;
}
- public static Bitmap createPillWithShadow(int rectColor, int width, int height) {
- float shadowRadius = height * 1f / 32;
- float shadowYOffset = height * 1f / 16;
- return createPillWithShadow(rectColor, width, height, shadowRadius, shadowYOffset,
- new RectF());
- }
-
- public static Bitmap createPillWithShadow(int rectColor, int width, int height,
- float shadowRadius, float shadowYOffset, RectF outRect) {
- int radius = height / 2;
-
- int centerX = Math.round(width / 2 + shadowRadius);
- int centerY = Math.round(radius + shadowRadius + shadowYOffset);
- int center = Math.max(centerX, centerY);
- int size = center * 2;
- Bitmap result = Bitmap.createBitmap(size, size, Config.ARGB_8888);
-
- outRect.set(0, 0, width, height);
- outRect.offsetTo(center - width / 2, center - height / 2);
-
- drawShadow(new Canvas(result), outRect, rectColor, shadowRadius, shadowYOffset, radius);
- return result;
- }
-
- public static void drawShadow(Canvas c, RectF bounds, int color,
- float shadowBlur, float keyShadowDistance, float radius) {
- Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
- p.setColor(color);
-
- // Key shadow
- p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
- ColorUtils.setAlphaComponent(Color.BLACK, KEY_SHADOW_ALPHA));
- c.drawRoundRect(bounds, radius, radius, p);
-
- // Ambient shadow
- p.setShadowLayer(shadowBlur, 0, 0,
- ColorUtils.setAlphaComponent(Color.BLACK, AMBIENT_SHADOW_ALPHA));
- c.drawRoundRect(bounds, radius, radius, p);
- }
-
public static ShadowGenerator getInstance(Context context) {
- Preconditions.assertNonUiThread();
+ // TODO: This currently fails as the system default icon also needs a shadow as it
+ // uses adaptive icon.
+ // Preconditions.assertNonUiThread();
synchronized (LOCK) {
if (sShadowGenerator == null) {
sShadowGenerator = new ShadowGenerator(context);
@@ -154,4 +115,58 @@
}
return scale;
}
+
+ public static class Builder {
+
+ public final RectF bounds = new RectF();
+ public final int color;
+
+ public int ambientShadowAlpha = AMBIENT_SHADOW_ALPHA;
+
+ public float shadowBlur;
+
+ public float keyShadowDistance;
+ public int keyShadowAlpha = KEY_SHADOW_ALPHA;
+ public float radius;
+
+ public Builder(int color) {
+ this.color = color;
+ }
+
+ public Builder setupBlurForSize(int height) {
+ shadowBlur = height * 1f / 32;
+ keyShadowDistance = height * 1f / 16;
+ return this;
+ }
+
+ public Bitmap createPill(int width, int height) {
+ radius = height / 2;
+
+ int centerX = Math.round(width / 2 + shadowBlur);
+ int centerY = Math.round(radius + shadowBlur + keyShadowDistance);
+ int center = Math.max(centerX, centerY);
+ bounds.set(0, 0, width, height);
+ bounds.offsetTo(center - width / 2, center - height / 2);
+
+ int size = center * 2;
+ Bitmap result = Bitmap.createBitmap(size, size, Config.ARGB_8888);
+ drawShadow(new Canvas(result));
+ return result;
+ }
+
+ public void drawShadow(Canvas c) {
+ Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ p.setColor(color);
+
+ // Key shadow
+ p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
+ ColorUtils.setAlphaComponent(Color.BLACK, keyShadowAlpha));
+ c.drawRoundRect(bounds, radius, radius, p);
+
+ // Ambient shadow
+ p.setShadowLayer(shadowBlur, 0, 0,
+ ColorUtils.setAlphaComponent(Color.BLACK, ambientShadowAlpha));
+ c.drawRoundRect(bounds, radius, radius, p);
+ }
+ }
}
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index d9c5143..816c1d4 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -152,7 +152,7 @@
for (ArrayList<String> map : deepShortcutMap.values()) {
writer.print(prefix + " ");
for (String str : map) {
- writer.print(str.toString() + ", ");
+ writer.print(str + ", ");
}
writer.println();
}
@@ -166,7 +166,7 @@
DumpTargetWrapper hotseat = new DumpTargetWrapper(ContainerType.HOTSEAT, 0);
LongArrayMap<DumpTargetWrapper> workspaces = new LongArrayMap<>();
for (int i = 0; i < workspaceScreens.size(); i++) {
- workspaces.put(new Long(workspaceScreens.get(i)),
+ workspaces.put(workspaceScreens.get(i),
new DumpTargetWrapper(ContainerType.WORKSPACE, i));
}
DumpTargetWrapper dtw;
@@ -183,7 +183,7 @@
if (fInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
hotseat.add(dtw);
} else if (fInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
- workspaces.get(new Long(fInfo.screenId)).add(dtw);
+ workspaces.get(fInfo.screenId).add(dtw);
}
}
// Add leaf nodes (L3): *Info
@@ -197,7 +197,7 @@
if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
hotseat.add(dtw);
} else if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
- workspaces.get(new Long(info.screenId)).add(dtw);
+ workspaces.get(info.screenId).add(dtw);
}
}
for (int i = 0; i < appWidgets.size(); i++) {
@@ -207,7 +207,7 @@
if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
hotseat.add(dtw);
} else if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
- workspaces.get(new Long(info.screenId)).add(dtw);
+ workspaces.get(info.screenId).add(dtw);
}
}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index b24d682..bb2d0b6 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -576,7 +576,8 @@
// available or not available. We do not need to track
// any future restore updates.
int status = c.restoreFlag &
- ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
+ ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED &
+ ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
if (!wasProviderReady) {
// If provider was not previously ready, update the
// status and UI flag.
@@ -584,9 +585,6 @@
// Id would be valid only if the widget restore broadcast was received.
if (isIdValid) {
status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
- } else {
- status &= ~LauncherAppWidgetInfo
- .FLAG_PROVIDER_NOT_READY;
}
}
appWidgetInfo.restoreStatus = status;
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index 1a93e11..1b7c87b 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -27,6 +27,7 @@
import android.service.notification.StatusBarNotification;
import android.view.View;
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.graphics.IconPalette;
@@ -105,7 +106,8 @@
if (autoCancel) {
launcher.getPopupDataProvider().cancelNotification(notificationKey);
}
- PopupContainerWithArrow.getOpen(launcher).close(true);
+ AbstractFloatingView.closeOpenContainer(launcher, AbstractFloatingView
+ .TYPE_POPUP_CONTAINER_WITH_ARROW);
}
public Drawable getIconForBackground(Context context, int background) {
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/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index 8dca699..baaa66a 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -16,25 +16,25 @@
package com.android.launcher3.notification;
+import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationChannel;
+import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.support.annotation.Nullable;
-import android.support.v4.util.Pair;
import android.text.TextUtils;
-
+import android.util.ArraySet;
+import android.util.Pair;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.PackageUserKey;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -44,6 +44,7 @@
* as well and when this service first connects. An instance of NotificationListener,
* and its methods for getting notifications, can be obtained via {@link #getInstanceIfConnected()}.
*/
+@TargetApi(Build.VERSION_CODES.O)
public class NotificationListener extends NotificationListenerService {
private static final int MSG_NOTIFICATION_POSTED = 1;
@@ -57,9 +58,9 @@
private final Handler mWorkerHandler;
private final Handler mUiHandler;
- private Ranking mTempRanking = new Ranking();
+ private final Ranking mTempRanking = new Ranking();
- private Handler.Callback mWorkerCallback = new Handler.Callback() {
+ private final Handler.Callback mWorkerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
@@ -80,7 +81,7 @@
}
};
- private Handler.Callback mUiCallback = new Handler.Callback() {
+ private final Handler.Callback mUiCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
@@ -163,9 +164,9 @@
* An object containing data to send to MSG_NOTIFICATION_POSTED targets.
*/
private class NotificationPostedMsg {
- PackageUserKey packageUserKey;
- NotificationKeyData notificationKey;
- boolean shouldBeFilteredOut;
+ final PackageUserKey packageUserKey;
+ final NotificationKeyData notificationKey;
+ final boolean shouldBeFilteredOut;
NotificationPostedMsg(StatusBarNotification sbn) {
packageUserKey = PackageUserKey.fromNotification(sbn);
@@ -189,7 +190,8 @@
StatusBarNotification[] notifications = NotificationListener.this
.getActiveNotifications(NotificationKeyData.extractKeysOnly(keys)
.toArray(new String[keys.size()]));
- return notifications == null ? Collections.EMPTY_LIST : Arrays.asList(notifications);
+ return notifications == null
+ ? Collections.<StatusBarNotification>emptyList() : Arrays.asList(notifications);
}
/**
@@ -201,7 +203,7 @@
private List<StatusBarNotification> filterNotifications(
StatusBarNotification[] notifications) {
if (notifications == null) return null;
- Set<Integer> removedNotifications = new HashSet<>();
+ Set<Integer> removedNotifications = new ArraySet<>();
for (int i = 0; i < notifications.length; i++) {
if (shouldBeFilteredOut(notifications[i])) {
removedNotifications.add(i);
diff --git a/src/com/android/launcher3/notification/SwipeHelper.java b/src/com/android/launcher3/notification/SwipeHelper.java
index 5f03252..ebbe5fc 100644
--- a/src/com/android/launcher3/notification/SwipeHelper.java
+++ b/src/com/android/launcher3/notification/SwipeHelper.java
@@ -24,23 +24,20 @@
import android.content.Context;
import android.graphics.RectF;
import android.os.Handler;
+import android.util.ArrayMap;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
-
import com.android.launcher3.R;
-import java.util.HashMap;
-
/**
* This class was copied from com.android.systemui.
*/
public class SwipeHelper {
- static final String TAG = "SwipeHelper";
- private static final boolean DEBUG = false;
+ private static final String TAG = "SwipeHelper";
private static final boolean DEBUG_INVALIDATE = false;
private static final boolean SLOW_ANIMATIONS = false; // DEBUG;
private static final boolean CONSTRAIN_SWIPE = true;
@@ -50,10 +47,10 @@
public static final int X = 0;
public static final int Y = 1;
- private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
- private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
- private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
- private int MAX_DISMISS_VELOCITY = 4000; // dp/sec
+ private static final float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
+ private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
+ private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
+ private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec
private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width
@@ -61,12 +58,12 @@
private float mMinSwipeProgress = 0f;
private float mMaxSwipeProgress = 1f;
- private FlingAnimationUtils mFlingAnimationUtils;
+ private final FlingAnimationUtils mFlingAnimationUtils;
private float mPagingTouchSlop;
- private Callback mCallback;
- private Handler mHandler;
- private int mSwipeDirection;
- private VelocityTracker mVelocityTracker;
+ private final Callback mCallback;
+ private final Handler mHandler;
+ private final int mSwipeDirection;
+ private final VelocityTracker mVelocityTracker;
private float mInitialTouchPos;
private float mPerpendicularInitialTouchPos;
@@ -80,14 +77,14 @@
private boolean mLongPressSent;
private LongPressListener mLongPressListener;
private Runnable mWatchLongPress;
- private long mLongPressTimeout;
+ private final long mLongPressTimeout;
final private int[] mTmpPos = new int[2];
- private int mFalsingThreshold;
+ private final int mFalsingThreshold;
private boolean mTouchAboveFalsingThreshold;
private boolean mDisableHwLayers;
- private HashMap<View, Animator> mDismissPendingMap = new HashMap<>();
+ private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>();
public SwipeHelper(int swipeDirection, Callback callback, Context context) {
mCallback = callback;
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
index ae10aed..8bcb979 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
@@ -50,7 +50,6 @@
Launcher l = Launcher.getLauncher(context);
setOnTouchListener(l.getHapticFeedbackTouchListener());
setOnClickListener(l);
- setOnLongClickListener(l);
setOnFocusChangeListener(l.mFocusHandler);
}
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
index 91fc1f0..6b992fc 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
@@ -137,7 +137,6 @@
mAllAppsHandle.setImageDrawable(getCaretDrawable());
mAllAppsHandle.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
mAllAppsHandle.setOnClickListener(mLauncher);
- mAllAppsHandle.setOnLongClickListener(mLauncher);
mAllAppsHandle.setOnFocusChangeListener(mLauncher.mFocusHandler);
mLauncher.setAllAppsButton(mAllAppsHandle);
}
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 5463ef7..77375fa 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) {
@@ -449,7 +459,9 @@
x += mIsLeftAligned ? xOffset : -xOffset;
// Open above icon if there is room.
- int iconHeight = icon.getIcon().getBounds().height();
+ int iconHeight = icon.getIcon() != null
+ ? icon.getIcon().getBounds().height()
+ : icon.getHeight();
int y = mTempRect.top + icon.getPaddingTop() - height;
mIsAboveIcon = y > dragLayer.getTop() + insets.top;
if (!mIsAboveIcon) {
@@ -639,11 +651,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 +688,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 +706,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 +759,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;
}
@@ -827,6 +867,9 @@
revealAnim.setDuration((long) res.getInteger(R.integer.config_popupOpenCloseDuration));
revealAnim.setInterpolator(new AccelerateDecelerateInterpolator());
+ // Animate original icon's text back in.
+ closeAnim.play(mOriginalIcon.createTextAlphaAnimator(true /* fadeIn */));
+
closeAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/src/com/android/launcher3/popup/PopupItemView.java b/src/com/android/launcher3/popup/PopupItemView.java
index 05cadb6..8ec051b 100644
--- a/src/com/android/launcher3/popup/PopupItemView.java
+++ b/src/com/android/launcher3/popup/PopupItemView.java
@@ -100,22 +100,24 @@
// Clip children to this item's rounded corners.
int cornerWidth = mRoundedCornerBitmap.getWidth();
int cornerHeight = mRoundedCornerBitmap.getHeight();
+ int cornerCenterX = Math.round(cornerWidth / 2f);
+ int cornerCenterY = Math.round(cornerHeight / 2f);
if ((mRoundedCorners & ROUNDED_TOP_CORNERS) != 0) {
// Clip top left corner.
mMatrix.reset();
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
// Clip top right corner.
- mMatrix.setRotate(90, cornerWidth / 2, cornerHeight / 2);
+ mMatrix.setRotate(90, cornerCenterX, cornerCenterY);
mMatrix.postTranslate(canvas.getWidth() - cornerWidth, 0);
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
}
if ((mRoundedCorners & ROUNDED_BOTTOM_CORNERS) != 0) {
// Clip bottom right corner.
- mMatrix.setRotate(180, cornerWidth / 2, cornerHeight / 2);
+ mMatrix.setRotate(180, cornerCenterX, cornerCenterY);
mMatrix.postTranslate(canvas.getWidth() - cornerWidth, canvas.getHeight() - cornerHeight);
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
// Clip bottom left corner.
- mMatrix.setRotate(270, cornerWidth / 2, cornerHeight / 2);
+ mMatrix.setRotate(270, cornerCenterX, cornerCenterY);
mMatrix.postTranslate(0, canvas.getHeight() - cornerHeight);
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
}
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..8785a56 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
@@ -91,8 +104,8 @@
@Override
public boolean onLongClick(View v) {
- // Return early if this is not initiated from a touch or not the correct view
- if (!v.isInTouchMode() || !(v.getParent() instanceof DeepShortcutView)) return false;
+ // Return early if not the correct view
+ if (!(v.getParent() instanceof DeepShortcutView)) return false;
// Return early if global dragging is not enabled
if (!mLauncher.isDraggingEnabled()) return false;
// Return early if an item is already being dragged (e.g. when long-pressing two shortcuts)
@@ -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/src/com/android/launcher3/util/SystemUiController.java b/src/com/android/launcher3/util/SystemUiController.java
new file mode 100644
index 0000000..6b5b095
--- /dev/null
+++ b/src/com/android/launcher3/util/SystemUiController.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.util;
+
+import android.view.View;
+import android.view.Window;
+
+import com.android.launcher3.Utilities;
+
+/**
+ * Utility class to manage various window flags to control system UI.
+ */
+public class SystemUiController {
+
+ // Various UI states in increasing order of priority
+ public static final int UI_STATE_BASE_WINDOW = 0;
+ public static final int UI_STATE_ALL_APPS = 1;
+ public static final int UI_STATE_WIDGET_BOTTOM_SHEET = 2;
+
+ public static final int FLAG_LIGHT_NAV = 1 << 0;
+ public static final int FLAG_DARK_NAV = 1 << 1;
+ public static final int FLAG_LIGHT_STATUS = 1 << 2;
+ public static final int FLAG_DARK_STATUS = 1 << 3;
+
+ private final Window mWindow;
+ private final int[] mStates = new int[3];
+
+ public SystemUiController(Window window) {
+ mWindow = window;
+ }
+
+ public void updateUiState(int uiState, boolean isLight) {
+ updateUiState(uiState, isLight
+ ? (FLAG_LIGHT_NAV | FLAG_LIGHT_STATUS) : (FLAG_DARK_NAV | FLAG_DARK_STATUS));
+ }
+
+ public void updateUiState(int uiState, int flags) {
+ if (mStates[uiState] == flags) {
+ return;
+ }
+ mStates[uiState] = flags;
+
+ int oldFlags = mWindow.getDecorView().getSystemUiVisibility();
+ // Apply the state flags in priority order
+ int newFlags = oldFlags;
+ for (int stateFlag : mStates) {
+ if (Utilities.isAtLeastO()) {
+ if ((stateFlag & FLAG_LIGHT_NAV) != 0) {
+ newFlags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+ } else if ((stateFlag & FLAG_DARK_NAV) != 0) {
+ newFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
+ }
+ }
+
+ if ((stateFlag & FLAG_LIGHT_STATUS) != 0) {
+ newFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+ } else if ((stateFlag & FLAG_DARK_STATUS) != 0) {
+ newFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+ }
+ }
+ if (newFlags != oldFlags) {
+ mWindow.getDecorView().setSystemUiVisibility(newFlags);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
new file mode 100644
index 0000000..c0b5fe1
--- /dev/null
+++ b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.views;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Region;
+import android.support.v4.graphics.ColorUtils;
+import android.util.AttributeSet;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.R;
+
+/**
+ * Extension of {@link BubbleTextView} which draws two shadows on the text (ambient and key shadows}
+ */
+public class DoubleShadowBubbleTextView extends BubbleTextView {
+
+ private final ShadowInfo mShadowInfo;
+
+ public DoubleShadowBubbleTextView(Context context) {
+ this(context, null);
+ }
+
+ public DoubleShadowBubbleTextView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public DoubleShadowBubbleTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mShadowInfo = new ShadowInfo(context, attrs, defStyle);
+ setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0, mShadowInfo.ambientShadowColor);
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ // If text is transparent, don't draw any shadow
+ int alpha = Color.alpha(getCurrentTextColor());
+ if (alpha == 0) {
+ getPaint().clearShadowLayer();
+ super.onDraw(canvas);
+ return;
+ }
+
+ // We enhance the shadow by drawing the shadow twice
+ getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0,
+ ColorUtils.setAlphaComponent(mShadowInfo.ambientShadowColor, alpha));
+
+ drawWithoutBadge(canvas);
+ canvas.save(Canvas.CLIP_SAVE_FLAG);
+ canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
+ getScrollX() + getWidth(),
+ getScrollY() + getHeight(), Region.Op.INTERSECT);
+
+ getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f, mShadowInfo.keyShadowOffset,
+ ColorUtils.setAlphaComponent(mShadowInfo.keyShadowColor, alpha));
+ drawWithoutBadge(canvas);
+ canvas.restore();
+
+ drawBadgeIfNecessary(canvas);
+ }
+
+ public static class ShadowInfo {
+ public final float ambientShadowBlur;
+ public final int ambientShadowColor;
+
+ public final float keyShadowBlur;
+ public final float keyShadowOffset;
+ public final int keyShadowColor;
+
+ public ShadowInfo(Context c, AttributeSet attrs, int defStyle) {
+
+ TypedArray a = c.obtainStyledAttributes(
+ attrs, R.styleable.ShadowInfo, defStyle, 0);
+
+ ambientShadowBlur = a.getDimension(R.styleable.ShadowInfo_ambientShadowBlur, 0);
+ ambientShadowColor = a.getColor(R.styleable.ShadowInfo_ambientShadowColor, 0);
+
+ keyShadowBlur = a.getDimension(R.styleable.ShadowInfo_keyShadowBlur, 0);
+ keyShadowOffset = a.getDimension(R.styleable.ShadowInfo_keyShadowOffset, 0);
+ keyShadowColor = a.getColor(R.styleable.ShadowInfo_keyShadowColor, 0);
+ a.recycle();
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
new file mode 100644
index 0000000..7b5bcdb
--- /dev/null
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -0,0 +1,356 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.views;
+
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+import android.util.Property;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.TextView;
+
+import com.android.launcher3.BaseRecyclerView;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.graphics.FastScrollThumbDrawable;
+import com.android.launcher3.util.Themes;
+
+/**
+ * The track and scrollbar that shows when you scroll the list.
+ */
+public class RecyclerViewFastScroller extends View {
+
+ private static final int SCROLL_DELTA_THRESHOLD_DP = 4;
+
+ private static final Property<RecyclerViewFastScroller, Integer> TRACK_WIDTH =
+ new Property<RecyclerViewFastScroller, Integer>(Integer.class, "width") {
+
+ @Override
+ public Integer get(RecyclerViewFastScroller scrollBar) {
+ return scrollBar.mWidth;
+ }
+
+ @Override
+ public void set(RecyclerViewFastScroller scrollBar, Integer value) {
+ scrollBar.setTrackWidth(value);
+ }
+ };
+
+ private final static int MAX_TRACK_ALPHA = 30;
+ private final static int SCROLL_BAR_VIS_DURATION = 150;
+ private static final float FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR = 0.75f;
+
+ private final int mMinWidth;
+ private final int mMaxWidth;
+ private final int mThumbPadding;
+
+ /** Keeps the last known scrolling delta/velocity along y-axis. */
+ private int mDy = 0;
+ private final float mDeltaThreshold;
+
+ private final ViewConfiguration mConfig;
+
+ // Current width of the track
+ private int mWidth;
+ private ObjectAnimator mWidthAnimator;
+
+ private final Paint mThumbPaint;
+ protected final int mThumbHeight;
+
+ private final Paint mTrackPaint;
+
+ private float mLastTouchY;
+ private boolean mIsDragging;
+ private boolean mIsThumbDetached;
+ private final boolean mCanThumbDetach;
+ private boolean mIgnoreDragGesture;
+
+ // This is the offset from the top of the scrollbar when the user first starts touching. To
+ // prevent jumping, this offset is applied as the user scrolls.
+ protected int mTouchOffsetY;
+ protected int mThumbOffsetY;
+
+ // Fast scroller popup
+ private TextView mPopupView;
+ private boolean mPopupVisible;
+ private String mPopupSectionName;
+
+ protected BaseRecyclerView mRv;
+
+ private int mDownX;
+ private int mDownY;
+ private int mLastY;
+
+ public RecyclerViewFastScroller(Context context) {
+ this(context, null);
+ }
+
+ public RecyclerViewFastScroller(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public RecyclerViewFastScroller(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ mTrackPaint = new Paint();
+ mTrackPaint.setColor(Themes.getAttrColor(context, android.R.attr.textColorPrimary));
+ mTrackPaint.setAlpha(MAX_TRACK_ALPHA);
+
+ mThumbPaint = new Paint();
+ mThumbPaint.setAntiAlias(true);
+ mThumbPaint.setColor(Themes.getColorAccent(context));
+ mThumbPaint.setStyle(Paint.Style.FILL);
+
+ Resources res = getResources();
+ mWidth = mMinWidth = res.getDimensionPixelSize(R.dimen.fastscroll_track_min_width);
+ mMaxWidth = res.getDimensionPixelSize(R.dimen.fastscroll_track_max_width);
+
+ mThumbPadding = res.getDimensionPixelSize(R.dimen.fastscroll_thumb_padding);
+ mThumbHeight = res.getDimensionPixelSize(R.dimen.fastscroll_thumb_height);
+
+ mConfig = ViewConfiguration.get(context);
+ mDeltaThreshold = res.getDisplayMetrics().density * SCROLL_DELTA_THRESHOLD_DP;
+
+ TypedArray ta =
+ context.obtainStyledAttributes(attrs, R.styleable.RecyclerViewFastScroller, defStyleAttr, 0);
+ mCanThumbDetach = ta.getBoolean(R.styleable.RecyclerViewFastScroller_canThumbDetach, false);
+ ta.recycle();
+ }
+
+ public void setRecyclerView(BaseRecyclerView rv, TextView popupView) {
+ mRv = rv;
+ mRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ mDy = dy;
+
+ // TODO(winsonc): If we want to animate the section heads while scrolling, we can
+ // initiate that here if the recycler view scroll state is not
+ // RecyclerView.SCROLL_STATE_IDLE.
+
+ mRv.onUpdateScrollbar(dy);
+ }
+ });
+
+ mPopupView = popupView;
+ mPopupView.setBackground(
+ new FastScrollThumbDrawable(mThumbPaint, Utilities.isRtl(getResources())));
+ }
+
+ public void reattachThumbToScroll() {
+ mIsThumbDetached = false;
+ }
+
+ public void setThumbOffsetY(int y) {
+ if (mThumbOffsetY == y) {
+ return;
+ }
+ mThumbOffsetY = y;
+ invalidate();
+ }
+
+ public int getThumbOffsetY() {
+ return mThumbOffsetY;
+ }
+
+ private void setTrackWidth(int width) {
+ if (mWidth == width) {
+ return;
+ }
+ mWidth = width;
+ invalidate();
+ }
+
+ public int getThumbHeight() {
+ return mThumbHeight;
+ }
+
+ public boolean isDraggingThumb() {
+ return mIsDragging;
+ }
+
+ public boolean isThumbDetached() {
+ return mIsThumbDetached;
+ }
+
+ /**
+ * Handles the touch event and determines whether to show the fast scroller (or updates it if
+ * it is already showing).
+ */
+ public boolean handleTouchEvent(MotionEvent ev) {
+ int x = (int) ev.getX();
+ int y = (int) ev.getY();
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ // Keep track of the down positions
+ mDownX = x;
+ mDownY = mLastY = y;
+
+ if ((Math.abs(mDy) < mDeltaThreshold &&
+ mRv.getScrollState() != RecyclerView.SCROLL_STATE_IDLE)) {
+ // now the touch events are being passed to the {@link WidgetCell} until the
+ // touch sequence goes over the touch slop.
+ mRv.stopScroll();
+ }
+ if (isNearThumb(x, y)) {
+ mTouchOffsetY = mDownY - mThumbOffsetY;
+ } else if (FeatureFlags.LAUNCHER3_DIRECT_SCROLL
+ && mRv.supportsFastScrolling()
+ && isNearScrollBar(mDownX)) {
+ calcTouchOffsetAndPrepToFastScroll(mDownY, mLastY);
+ updateFastScrollSectionNameAndThumbOffset(mLastY, y);
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ mLastY = y;
+
+ // Check if we should start scrolling, but ignore this fastscroll gesture if we have
+ // exceeded some fixed movement
+ mIgnoreDragGesture |= Math.abs(y - mDownY) > mConfig.getScaledPagingTouchSlop();
+ if (!mIsDragging && !mIgnoreDragGesture && mRv.supportsFastScrolling() &&
+ isNearThumb(mDownX, mLastY) &&
+ Math.abs(y - mDownY) > mConfig.getScaledTouchSlop()) {
+ calcTouchOffsetAndPrepToFastScroll(mDownY, mLastY);
+ }
+ if (mIsDragging) {
+ updateFastScrollSectionNameAndThumbOffset(mLastY, y);
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mRv.onFastScrollCompleted();
+ mTouchOffsetY = 0;
+ mLastTouchY = 0;
+ mIgnoreDragGesture = false;
+ if (mIsDragging) {
+ mIsDragging = false;
+ animatePopupVisibility(false);
+ showActiveScrollbar(false);
+ }
+ break;
+ }
+ return mIsDragging;
+ }
+
+ private void calcTouchOffsetAndPrepToFastScroll(int downY, int lastY) {
+ mRv.getParent().requestDisallowInterceptTouchEvent(true);
+ mIsDragging = true;
+ if (mCanThumbDetach) {
+ mIsThumbDetached = true;
+ }
+ mTouchOffsetY += (lastY - downY);
+ animatePopupVisibility(true);
+ showActiveScrollbar(true);
+ }
+
+ private void updateFastScrollSectionNameAndThumbOffset(int lastY, int y) {
+ // Update the fastscroller section name at this touch position
+ int bottom = mRv.getScrollbarTrackHeight() - mThumbHeight;
+ float boundedY = (float) Math.max(0, Math.min(bottom, y - mTouchOffsetY));
+ String sectionName = mRv.scrollToPositionAtProgress(boundedY / bottom);
+ if (!sectionName.equals(mPopupSectionName)) {
+ mPopupSectionName = sectionName;
+ mPopupView.setText(sectionName);
+ }
+ animatePopupVisibility(!sectionName.isEmpty());
+ updatePopupY(lastY);
+ mLastTouchY = boundedY;
+ setThumbOffsetY((int) mLastTouchY);
+ }
+
+ public void onDraw(Canvas canvas) {
+ if (mThumbOffsetY < 0) {
+ return;
+ }
+ int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ canvas.translate(getWidth() / 2, mRv.getPaddingTop());
+ // Draw the track
+ float halfW = mWidth / 2;
+ canvas.drawRoundRect(-halfW, 0, halfW, mRv.getScrollbarTrackHeight(),
+ mWidth, mWidth, mTrackPaint);
+
+ canvas.translate(0, mThumbOffsetY);
+ halfW += mThumbPadding;
+ float r = mWidth + mThumbPadding + mThumbPadding;
+ canvas.drawRoundRect(-halfW, 0, halfW, mThumbHeight, r, r, mThumbPaint);
+ canvas.restoreToCount(saveCount);
+ }
+
+
+ /**
+ * Animates the width of the scrollbar.
+ */
+ private void showActiveScrollbar(boolean isScrolling) {
+ if (mWidthAnimator != null) {
+ mWidthAnimator.cancel();
+ }
+
+ mWidthAnimator = ObjectAnimator.ofInt(this, TRACK_WIDTH,
+ isScrolling ? mMaxWidth : mMinWidth);
+ mWidthAnimator.setDuration(SCROLL_BAR_VIS_DURATION);
+ mWidthAnimator.start();
+ }
+
+ /**
+ * Returns whether the specified point is inside the thumb bounds.
+ */
+ private boolean isNearThumb(int x, int y) {
+ int offset = y - mRv.getPaddingTop() - mThumbOffsetY;
+
+ return x >= 0 && x < getWidth() && offset >= 0 && offset <= mThumbHeight;
+ }
+
+ /**
+ * Returns true if AllAppsTransitionController can handle vertical motion
+ * beginning at this point.
+ */
+ public boolean shouldBlockIntercept(int x, int y) {
+ return isNearThumb(x, y);
+ }
+
+ /**
+ * Returns whether the specified x position is near the scroll bar.
+ */
+ public boolean isNearScrollBar(int x) {
+ return x >= (getWidth() - mMaxWidth) / 2 && x <= (getWidth() + mMaxWidth) / 2;
+ }
+
+ private void animatePopupVisibility(boolean visible) {
+ if (mPopupVisible != visible) {
+ mPopupVisible = visible;
+ mPopupView.animate().cancel();
+ mPopupView.animate().alpha(visible ? 1f : 0f).setDuration(visible ? 200 : 150).start();
+ }
+ }
+
+ private void updatePopupY(int lastTouchY) {
+ int height = mPopupView.getHeight();
+ float top = lastTouchY - (FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR * height)
+ + mRv.getPaddingTop();
+ top = Utilities.boundToRange(top,
+ mMaxWidth, mRv.getScrollbarTrackHeight() - mMaxWidth - height);
+ mPopupView.setTranslationY(top);
+ }
+}
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 6628971..19be28d 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -116,7 +116,7 @@
} else {
PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) mAddInfo;
Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(app.getIconCache());
- preview = LauncherIcons.createScaledBitmapWithoutShadow(icon, launcher, Build.VERSION_CODES.O);
+ preview = LauncherIcons.createScaledBitmapWithoutShadow(icon, launcher, 0);
mAddInfo.spanX = mAddInfo.spanY = 1;
scale = ((float) launcher.getDeviceProfile().iconSizePx) / preview.getWidth();
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 5fe00c2..fff3472 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -21,14 +21,13 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Rect;
-import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.TextView;
@@ -48,6 +47,7 @@
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.TouchController;
import java.util.List;
@@ -69,7 +69,6 @@
private Interpolator mFastOutSlowInInterpolator;
private VerticalPullDetector.ScrollInterpolator mScrollInterpolator;
private Rect mInsets;
- private boolean mWasNavBarLight;
private VerticalPullDetector mVerticalPullDetector;
public WidgetsBottomSheet(Context context, AttributeSet attrs) {
@@ -77,11 +76,12 @@
}
public WidgetsBottomSheet(Context context, AttributeSet attrs, int defStyleAttr) {
- super(new ContextThemeWrapper(context, R.style.WidgetContainerTheme), attrs, defStyleAttr);
+ super(context, attrs, defStyleAttr);
setWillNotDraw(false);
mLauncher = Launcher.getLauncher(context);
mOpenCloseAnimator = LauncherAnimUtils.ofPropertyValuesHolder(this);
- mFastOutSlowInInterpolator = new FastOutSlowInInterpolator();
+ mFastOutSlowInInterpolator =
+ AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
mScrollInterpolator = new VerticalPullDetector.ScrollInterpolator();
mInsets = new Rect();
mVerticalPullDetector = new VerticalPullDetector(context);
@@ -103,8 +103,6 @@
onWidgetsBound();
- mWasNavBarLight = (mLauncher.getWindow().getDecorView().getSystemUiVisibility()
- & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0;
mLauncher.getDragLayer().addView(this);
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
setTranslationY(mTranslationYClosed);
@@ -180,7 +178,8 @@
return;
}
mIsOpen = true;
- setLightNavBar(true);
+ mLauncher.getSystemUiController().updateUiState(
+ SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, SystemUiController.FLAG_LIGHT_NAV);
if (animate) {
mOpenCloseAnimator.setValues(new PropertyListBuilder()
.translationY(mTranslationYOpen).build());
@@ -211,7 +210,8 @@
mIsOpen = false;
mVerticalPullDetector.finishedScrolling();
((ViewGroup) getParent()).removeView(WidgetsBottomSheet.this);
- setLightNavBar(mWasNavBarLight);
+ mLauncher.getSystemUiController().updateUiState(
+ SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, 0);
}
});
mOpenCloseAnimator.setInterpolator(mVerticalPullDetector.isIdleState()
@@ -219,15 +219,12 @@
mOpenCloseAnimator.start();
} else {
setTranslationY(mTranslationYClosed);
- setLightNavBar(mWasNavBarLight);
+ mLauncher.getSystemUiController().updateUiState(
+ SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, 0);
mIsOpen = false;
}
}
- private void setLightNavBar(boolean lightNavBar) {
- mLauncher.activateLightSystemBars(lightNavBar, false /* statusBar */, true /* navBar */);
- }
-
@Override
protected boolean isOfType(@FloatingViewType int type) {
return (type & TYPE_WIDGETS_BOTTOM_SHEET) != 0;
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index 4e296bf..14a9d17 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -139,8 +139,6 @@
if (LOGD) {
Log.d(TAG, String.format("onLongClick [v=%s]", v));
}
- // Return early if this is not initiated from a touch
- if (!v.isInTouchMode()) return false;
// When we are in transition, disregard long clicks
if (mLauncher.getWorkspace().isSwitchingState()) return false;
// Return if global dragging is not enabled
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index f47ca3eeb..9730a82 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -59,10 +59,6 @@
setLayoutManager(new LinearLayoutManager(getContext()));
}
- public int getFastScrollerTrackColor(int defaultTrackColor) {
- return Color.WHITE;
- }
-
@Override
public void setAdapter(Adapter adapter) {
super.setAdapter(adapter);
diff --git a/src_flags/com/android/launcher3/config/FeatureFlags.java b/src_flags/com/android/launcher3/config/FeatureFlags.java
index ed169b6..42a110c 100644
--- a/src_flags/com/android/launcher3/config/FeatureFlags.java
+++ b/src_flags/com/android/launcher3/config/FeatureFlags.java
@@ -37,11 +37,13 @@
// When enabled while all-apps open, the soft input will be set to adjust resize .
public static boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = true;
// When enabled the promise icon is visible in all apps while installation an app.
- public static boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = true;
+ public static boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = false;
// When enabled uses the AllAppsRadialGradientAndScrimDrawable for all apps
public static boolean LAUNCHER3_GRADIENT_ALL_APPS = true;
// When enabled allows use of physics based motions in the Launcher.
public static boolean LAUNCHER3_PHYSICS = true;
+ // When enabled allows use of spring motions on the icons.
+ public static boolean LAUNCHER3_SPRING_ICONS = true;
// Feature flag to enable moving the QSB on the 0th screen of the workspace.
public static final boolean QSB_ON_FIRST_SCREEN = true;
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
diff --git a/tests/src/com/android/launcher3/util/TestLauncherProvider.java b/tests/src/com/android/launcher3/util/TestLauncherProvider.java
index 6ca2121..1d6c18b 100644
--- a/tests/src/com/android/launcher3/util/TestLauncherProvider.java
+++ b/tests/src/com/android/launcher3/util/TestLauncherProvider.java
@@ -1,6 +1,7 @@
package com.android.launcher3.util;
import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.android.launcher3.LauncherProvider;
@@ -43,5 +44,8 @@
@Override
protected void onEmptyDbCreated() { }
+
+ @Override
+ protected void handleOneTimeDataUpgrade(SQLiteDatabase db) { }
}
}
\ No newline at end of file