Merge "Dynamic Color Tile Update" into udc-dev
diff --git a/res/drawable/carousel_item_card_background.xml b/res/drawable/carousel_item_card_background.xml
new file mode 100644
index 0000000..946d279
--- /dev/null
+++ b/res/drawable/carousel_item_card_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2023 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="@color/color_surface" />
+ <corners android:radius="16dp" />
+</shape>
\ No newline at end of file
diff --git a/res/drawable/ic_settings.xml b/res/drawable/ic_settings.xml
index 3b9076e..b4341a6 100644
--- a/res/drawable/ic_settings.xml
+++ b/res/drawable/ic_settings.xml
@@ -19,7 +19,7 @@
android:viewportWidth="960"
android:viewportHeight="960"
android:tintMode="multiply"
- android:tint="@color/color_accent_primary">
+ android:tint="@color/text_color_primary">
<path
android:fillColor="@android:color/white"
android:pathData="M370,880L354,752Q341,747 329.5,740Q318,733 307,725L188,775L78,585L181,507Q180,500 180,493.5Q180,487 180,480Q180,473 180,466.5Q180,460 181,453L78,375L188,185L307,235Q318,227 330,220Q342,213 354,208L370,80L590,80L606,208Q619,213 630.5,220Q642,227 653,235L772,185L882,375L779,453Q780,460 780,466.5Q780,473 780,480Q780,487 780,493.5Q780,500 778,507L881,585L771,775L653,725Q642,733 630,740Q618,747 606,752L590,880L370,880ZM440,800L519,800L533,694Q564,686 590.5,670.5Q617,655 639,633L738,674L777,606L691,541Q696,527 698,511.5Q700,496 700,480Q700,464 698,448.5Q696,433 691,419L777,354L738,286L639,328Q617,305 590.5,289.5Q564,274 533,266L520,160L441,160L427,266Q396,274 369.5,289.5Q343,305 321,327L222,286L183,354L269,418Q264,433 262,448Q260,463 260,480Q260,496 262,511Q264,526 269,541L183,606L222,674L321,632Q343,655 369.5,670.5Q396,686 427,694L440,800ZM482,620Q540,620 581,579Q622,538 622,480Q622,422 581,381Q540,340 482,340Q423,340 382.5,381Q342,422 342,480Q342,538 382.5,579Q423,620 482,620ZM480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480Z"/>
diff --git a/res/layout/clock_carousel.xml b/res/layout/clock_carousel.xml
index dbeb4dd..25af031 100644
--- a/res/layout/clock_carousel.xml
+++ b/res/layout/clock_carousel.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
app:layoutDescription="@xml/carousel_scene">
- <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ <FrameLayout
android:id="@+id/item_view_0"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
@@ -30,14 +30,28 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/item_view_1"
app:layout_constraintTop_toTopOf="parent">
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:clipChildren="false" />
- </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
- <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ <View
+ android:id="@+id/item_card_0"
+ android:layout_width="@dimen/clock_carousel_item_card_width"
+ android:layout_height="@dimen/clock_carousel_item_card_height"
+ android:layout_gravity="center"
+ android:background="@drawable/carousel_item_card_background"/>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/clock_scale_view_0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:id="@+id/clock_host_view_0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:clipChildren="false" />
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+ </FrameLayout>
+
+ <FrameLayout
android:id="@+id/item_view_1"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
@@ -45,14 +59,28 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/item_view_2"
app:layout_constraintTop_toTopOf="parent" >
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:clipChildren="false"/>
- </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
- <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ <View
+ android:id="@+id/item_card_1"
+ android:layout_width="@dimen/clock_carousel_item_card_width"
+ android:layout_height="@dimen/clock_carousel_item_card_height"
+ android:layout_gravity="center"
+ android:background="@drawable/carousel_item_card_background"/>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/clock_scale_view_1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:id="@+id/clock_host_view_1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:clipChildren="false"/>
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+ </FrameLayout>
+
+ <FrameLayout
android:id="@+id/item_view_2"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
@@ -61,42 +89,85 @@
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:clipChildren="false"/>
- </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
- <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ <View
+ android:id="@+id/item_card_2"
+ android:layout_width="@dimen/clock_carousel_item_card_width"
+ android:layout_height="@dimen/clock_carousel_item_card_height"
+ android:alpha="0.0"
+ android:layout_gravity="center"
+ android:background="@drawable/carousel_item_card_background"/>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/clock_scale_view_2"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:id="@+id/clock_host_view_2"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:clipChildren="false"/>
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+ </FrameLayout>
+
+ <FrameLayout
android:id="@+id/item_view_3"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
android:layout_marginStart="@dimen/clock_carousel_item_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/item_view_2"
- app:layout_constraintTop_toTopOf="parent" >
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:clipChildren="false"/>
- </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+ app:layout_constraintTop_toTopOf="parent">
- <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ <View
+ android:id="@+id/item_card_3"
+ android:layout_width="@dimen/clock_carousel_item_card_width"
+ android:layout_height="@dimen/clock_carousel_item_card_height"
+ android:layout_gravity="center"
+ android:background="@drawable/carousel_item_card_background"/>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/clock_scale_view_3"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:id="@+id/clock_host_view_3"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:clipChildren="false"/>
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+ </FrameLayout>
+
+ <FrameLayout
android:id="@+id/item_view_4"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
android:layout_marginStart="@dimen/clock_carousel_item_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/item_view_3"
- app:layout_constraintTop_toTopOf="parent" >
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <View
+ android:id="@+id/item_card_4"
+ android:layout_width="@dimen/clock_carousel_item_card_width"
+ android:layout_height="@dimen/clock_carousel_item_card_height"
android:layout_gravity="center"
- android:clipChildren="false" />
- </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+ android:background="@drawable/carousel_item_card_background"/>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/clock_scale_view_4"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:id="@+id/clock_host_view_4"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:clipChildren="false" />
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+ </FrameLayout>
<androidx.constraintlayout.helper.widget.Carousel
android:id="@+id/carousel"
diff --git a/res/layout/clock_color_and_size_button.xml b/res/layout/clock_color_and_size_button.xml
index ff5a519..d54c33d 100644
--- a/res/layout/clock_color_and_size_button.xml
+++ b/res/layout/clock_color_and_size_button.xml
@@ -14,11 +14,13 @@
android:layout_height="@dimen/clock_color_size_button_icon_size"
android:src="@drawable/ic_settings"
android:importantForAccessibility="no"
+ android:drawableTint="@color/text_color_primary"
android:layout_marginEnd="@dimen/clock_color_size_button_icon_margin_end"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textColor="@color/color_accent_primary"
+ android:textColor="@color/text_color_primary"
android:text="@string/clock_color_and_size_title" />
+
</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/clock_color_option.xml b/res/layout/clock_color_option.xml
new file mode 100644
index 0000000..4203a39
--- /dev/null
+++ b/res/layout/clock_color_option.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2023 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.
+-->
+<!-- Content description is set programmatically on the parent FrameLayout -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:clipChildren="false">
+ <FrameLayout
+ android:id="@+id/icon_container"
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size"
+ android:clipChildren="false">
+
+ <ImageView
+ android:id="@id/selection_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_border"
+ android:alpha="0"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_background"
+ android:importantForAccessibility="no" />
+
+ <FrameLayout
+ android:id="@id/foreground"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ImageView
+ android:id="@+id/color_preview_0"
+ android:layout_width="@dimen/component_color_chip_small_radius_default2"
+ android:layout_height="@dimen/component_color_chip_small_radius_default2"
+ android:layout_gravity="center"
+ android:layout_marginRight="@dimen/color_seed_chip_margin2"
+ android:layout_marginBottom="@dimen/color_seed_chip_margin2"
+ android:src="@drawable/color_chip_seed_filled0"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_1"
+ android:layout_width="@dimen/component_color_chip_small_radius_default2"
+ android:layout_height="@dimen/component_color_chip_small_radius_default2"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/color_seed_chip_margin2"
+ android:layout_marginBottom="@dimen/color_seed_chip_margin2"
+ android:src="@drawable/color_chip_seed_filled2"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_2"
+ android:layout_width="@dimen/component_color_chip_small_radius_default2"
+ android:layout_height="@dimen/component_color_chip_small_radius_default2"
+ android:layout_gravity="center"
+ android:layout_marginRight="@dimen/color_seed_chip_margin2"
+ android:layout_marginTop="@dimen/color_seed_chip_margin2"
+ android:src="@drawable/color_chip_seed_filled1"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_3"
+ android:layout_width="@dimen/component_color_chip_small_radius_default2"
+ android:layout_height="@dimen/component_color_chip_small_radius_default2"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/color_seed_chip_margin2"
+ android:layout_marginTop="@dimen/color_seed_chip_margin2"
+ android:src="@drawable/color_chip_seed_filled3"
+ android:importantForAccessibility="no" />
+ </FrameLayout>
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/option_bottom_margin"
+ android:textColor="@color/text_color_primary"
+ android:visibility="invisible"
+ android:gravity="center"
+ android:text="Placeholder for stable size calculation, please do not remove."
+ tools:ignore="HardcodedText" />
+</LinearLayout>
+
diff --git a/res/layout/clock_section_view.xml b/res/layout/clock_section_view.xml
index 31f08fc..0632601 100644
--- a/res/layout/clock_section_view.xml
+++ b/res/layout/clock_section_view.xml
@@ -20,7 +20,7 @@
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:clickable="true"
- android:paddingVertical="@dimen/section_top_padding"
+ android:paddingVertical="@dimen/section_padding"
android:paddingHorizontal="@dimen/section_horizontal_padding"
android:orientation="horizontal">
diff --git a/res/layout/dark_mode_section_view.xml b/res/layout/dark_mode_section_view.xml
index e1b4b81..27550e2 100644
--- a/res/layout/dark_mode_section_view.xml
+++ b/res/layout/dark_mode_section_view.xml
@@ -22,7 +22,7 @@
android:clickable="true"
android:gravity="center_vertical"
android:orientation="horizontal"
- android:paddingVertical="@dimen/section_vertical_padding"
+ android:paddingVertical="@dimen/section_padding"
android:paddingHorizontal="@dimen/section_horizontal_padding">
<TextView
diff --git a/res/layout/fragment_clock_settings.xml b/res/layout/fragment_clock_settings.xml
index 58232a7..d52ebdf 100644
--- a/res/layout/fragment_clock_settings.xml
+++ b/res/layout/fragment_clock_settings.xml
@@ -18,7 +18,9 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:clipChildren="false">
+
<FrameLayout
android:id="@+id/section_header_container"
android:layout_width="match_parent"
@@ -31,13 +33,13 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
- android:paddingTop="36dp"
+ android:paddingTop="20dp"
android:paddingBottom="40dp">
<include
android:id="@+id/lock_preview"
layout="@layout/wallpaper_preview_card"
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center" />
@@ -48,7 +50,6 @@
android:layout_gravity="center" />
</com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
-
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -123,7 +124,7 @@
without changing its size after the content is loaded into the RecyclerView.
-->
<include
- layout="@layout/color_option_2"
+ layout="@layout/clock_color_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" />
diff --git a/res/layout/grid_section_view.xml b/res/layout/grid_section_view.xml
index ee7b76f..a90ee64 100644
--- a/res/layout/grid_section_view.xml
+++ b/res/layout/grid_section_view.xml
@@ -20,7 +20,7 @@
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:clickable="true"
- android:paddingVertical="@dimen/section_top_padding"
+ android:paddingVertical="@dimen/section_padding"
android:paddingHorizontal="@dimen/section_horizontal_padding"
android:orientation="horizontal">
diff --git a/res/layout/keyguard_quick_affordance_section_view.xml b/res/layout/keyguard_quick_affordance_section_view.xml
index 458f659..7c5babb 100644
--- a/res/layout/keyguard_quick_affordance_section_view.xml
+++ b/res/layout/keyguard_quick_affordance_section_view.xml
@@ -16,11 +16,11 @@
-->
<com.android.customization.picker.quickaffordance.ui.view.KeyguardQuickAffordanceSectionView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:background="?selectableItemBackground"
android:clickable="true"
- android:paddingVertical="@dimen/section_top_padding"
+ android:paddingVertical="@dimen/option_section_vertical_padding"
android:paddingHorizontal="@dimen/section_horizontal_padding"
android:orientation="horizontal">
@@ -28,7 +28,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:layout_gravity="center">
<TextView
android:layout_width="match_parent"
@@ -51,6 +52,7 @@
android:importantForAccessibility="noHideDescendants"
android:gravity="center"
android:divider="@drawable/horizontal_divider_14dp"
+ android:layout_gravity="center"
android:showDividers="middle">
<ImageView
diff --git a/res/layout/more_settings_section_view.xml b/res/layout/more_settings_section_view.xml
index b60bb45..5745a27 100644
--- a/res/layout/more_settings_section_view.xml
+++ b/res/layout/more_settings_section_view.xml
@@ -20,7 +20,7 @@
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:clickable="true"
- android:paddingVertical="@dimen/section_top_padding"
+ android:paddingVertical="@dimen/section_padding"
android:paddingHorizontal="@dimen/section_horizontal_padding"
android:orientation="vertical">
diff --git a/res/layout/notification_section.xml b/res/layout/notification_section.xml
index 713624e..c89f2e3 100644
--- a/res/layout/notification_section.xml
+++ b/res/layout/notification_section.xml
@@ -22,7 +22,7 @@
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:clickable="true"
- android:paddingVertical="@dimen/section_top_padding"
+ android:paddingVertical="@dimen/section_padding"
android:paddingHorizontal="@dimen/section_horizontal_padding"
android:orientation="horizontal"
android:gravity="center_vertical">
@@ -31,6 +31,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
+ android:layout_gravity="center"
android:orientation="vertical">
<TextView
@@ -51,6 +52,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
+ android:layout_gravity="center"
style="@style/Switch.SettingsLib"
tools:ignore="UseSwitchCompatOrMaterialXml" />
diff --git a/res/layout/themed_icon_section_view.xml b/res/layout/themed_icon_section_view.xml
index 95be207..84ef3e8 100644
--- a/res/layout/themed_icon_section_view.xml
+++ b/res/layout/themed_icon_section_view.xml
@@ -22,7 +22,7 @@
android:clickable="true"
android:orientation="vertical"
android:paddingHorizontal="@dimen/section_horizontal_padding"
- android:paddingVertical="@dimen/section_vertical_padding">
+ android:paddingVertical="@dimen/section_padding">
<LinearLayout
android:layout_width="match_parent"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index cb4876a..18b38c8 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -33,7 +33,7 @@
<dimen name="options_container_width">0dp</dimen>
<dimen name="option_bottom_margin">8dp</dimen>
<dimen name="option_padding_horizontal">2dp</dimen>
- <dimen name="option_tile_width">82dp</dimen>
+ <dimen name="option_tile_width">80dp</dimen>
<dimen name="option_tile_radius">20dp</dimen>
<dimen name="option_tile_margin_horizontal">6dp</dimen>
<dimen name="option_tile_padding_vertical">12dp</dimen>
@@ -160,16 +160,14 @@
<dimen name="clock_carousel_item_height">380dp</dimen>
<dimen name="clock_carousel_item_margin">16dp</dimen>
<dimen name="clock_carousel_guideline_margin">140dp</dimen>
- <!-- Scale of the carousel items that are not selected and at the side -->
- <dimen name="clock_carousel_scale" format="float">0.5</dimen>
- <!-- Alpha of the carousel items that are not selected and at the side -->
- <dimen name="clock_carousel_alpha" format="float">0.4</dimen>
+ <dimen name="clock_carousel_item_card_width">100dp</dimen>
+ <dimen name="clock_carousel_item_card_height">108dp</dimen>
<!-- Clock color and size button -->
<dimen name="clock_color_size_button_min_height">32dp</dimen>
<dimen name="clock_color_size_button_horizontal_padding">12dp</dimen>
<dimen name="clock_color_size_button_vertical_padding">6dp</dimen>
<dimen name="clock_color_size_button_corner_radius">16dp</dimen>
- <dimen name="clock_color_size_button_icon_size">24dp</dimen>
- <dimen name="clock_color_size_button_icon_margin_end">8dp</dimen>
+ <dimen name="clock_color_size_button_icon_size">20dp</dimen>
+ <dimen name="clock_color_size_button_icon_margin_end">12dp</dimen>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 3991b65..87aae10 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -47,6 +47,7 @@
<item name="colorAccent">@color/accent_color</item>
<item name="colorSurface">@color/design_default_color_surface</item>
<item name="colorOnSurface">@color/design_default_color_on_surface</item>
+ <item name="android:textAllCaps">false</item>
</style>
<!-- Snackbar margin -->
diff --git a/res/xml/carousel_scene.xml b/res/xml/carousel_scene.xml
index e26ee14..267f0a1 100644
--- a/res/xml/carousel_scene.xml
+++ b/res/xml/carousel_scene.xml
@@ -42,12 +42,10 @@
android:id="@+id/item_view_0"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintEnd_toStartOf="@id/guideline_start"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
+
<Constraint
android:id="@+id/item_view_1"
android:layout_width="@dimen/clock_carousel_item_width"
@@ -58,13 +56,11 @@
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
+
<Constraint
android:id="@+id/item_view_2"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintStart_toStartOf="@id/guideline_end"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
@@ -73,9 +69,6 @@
android:id="@+id/item_view_3"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintStart_toEndOf="@+id/item_view_2"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
@@ -86,9 +79,6 @@
android:id="@+id/item_view_0"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintEnd_toStartOf="@+id/item_view_1"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
@@ -97,12 +87,10 @@
android:id="@+id/item_view_1"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintEnd_toStartOf="@id/guideline_start"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
+
<Constraint
android:id="@+id/item_view_2"
android:layout_width="@dimen/clock_carousel_item_width"
@@ -113,13 +101,11 @@
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
+
<Constraint
android:id="@+id/item_view_3"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintStart_toStartOf="@id/guideline_end"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
@@ -128,9 +114,6 @@
android:id="@+id/item_view_4"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintStart_toEndOf="@+id/item_view_3"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
@@ -141,9 +124,6 @@
android:id="@+id/item_view_1"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintEnd_toStartOf="@+id/item_view_2"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
@@ -152,12 +132,10 @@
android:id="@+id/item_view_2"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintEnd_toStartOf="@id/guideline_start"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
+
<Constraint
android:id="@+id/item_view_3"
android:layout_width="@dimen/clock_carousel_item_width"
@@ -168,16 +146,13 @@
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
+
<Constraint
android:id="@+id/item_view_4"
android:layout_width="@dimen/clock_carousel_item_width"
android:layout_height="@dimen/clock_carousel_item_height"
- android:scaleX="@dimen/clock_carousel_scale"
- android:scaleY="@dimen/clock_carousel_scale"
- android:alpha="@dimen/clock_carousel_alpha"
motion:layout_constraintStart_toStartOf="@id/guideline_end"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>
-
</MotionScene>
\ No newline at end of file
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
index 880a00b..9537365 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -137,6 +137,7 @@
secureSettingsRepository
.intSetting(
name = Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
+ defaultValue = DEFAULT_CLOCK_SIZE,
)
.map { setting -> setting == 1 }
.map { isDynamic -> if (isDynamic) ClockSize.DYNAMIC else ClockSize.SMALL }
@@ -189,5 +190,8 @@
// The color tone to apply to the selected color
private const val KEY_METADATA_COLOR_TONE_PROGRESS = "metadataColorToneProgress"
+
+ // The default clock size is 1, which means dynamic
+ private const val DEFAULT_CLOCK_SIZE = 1
}
}
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
index cf80dc1..8d5924e 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
@@ -30,14 +30,6 @@
import kotlinx.coroutines.launch
object ClockCarouselViewBinder {
- /**
- * The binding is used by the view where there is an action executed from another view, e.g.
- * toggling show/hide of the view that the binder is holding.
- */
- interface Binding {
- fun show()
- fun hide()
- }
@JvmStatic
fun bind(
@@ -46,7 +38,7 @@
viewModel: ClockCarouselViewModel,
clockViewFactory: ClockViewFactory,
lifecycleOwner: LifecycleOwner,
- ): Binding {
+ ) {
val singleClockHostView =
singleClockView.requireViewById<FrameLayout>(R.id.single_clock_host_view)
lifecycleOwner.lifecycleScope.launch {
@@ -67,6 +59,12 @@
}
launch {
+ viewModel.allClockIds.collect {
+ it.forEach { clockId -> clockViewFactory.updateTimeFormat(clockId) }
+ }
+ }
+
+ launch {
viewModel.selectedIndex.collect { selectedIndex ->
carouselView.setSelectedClockIndex(selectedIndex)
}
@@ -97,7 +95,9 @@
LifecycleEventObserver { source, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> {
- clockViewFactory.registerTimeTicker(source)
+ clockViewFactory.registerTimeTicker(source) {
+ !carouselView.isCarouselInTransition
+ }
}
Lifecycle.Event.ON_PAUSE -> {
clockViewFactory.unregisterTimeTicker(source)
@@ -106,15 +106,5 @@
}
}
)
-
- return object : Binding {
- override fun show() {
- viewModel.showClockCarousel(true)
- }
-
- override fun hide() {
- viewModel.showClockCarousel(false)
- }
- }
}
}
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
index 9a67c49..4664bd0 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -64,7 +64,7 @@
val colorOptionContainerView: RecyclerView = view.requireViewById(R.id.color_options)
val colorOptionAdapter =
OptionItemAdapter(
- layoutResourceId = R.layout.color_option_2,
+ layoutResourceId = R.layout.clock_color_option,
lifecycleOwner = lifecycleOwner,
bindIcon = { foregroundView: View, colorIcon: ColorOptionIconViewModel ->
val viewGroup = foregroundView as? ViewGroup
diff --git a/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt b/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
index b5e7c18..fc1e018 100644
--- a/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
+++ b/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
@@ -66,51 +66,50 @@
val colorViewModel = injector.getWallpaperColorsViewModel()
val displayUtils = injector.getDisplayUtils(context)
ScreenPreviewBinder.bind(
- activity = activity,
- previewView = lockScreenView,
- viewModel =
- ScreenPreviewViewModel(
- previewUtils =
- PreviewUtils(
- context = context,
- authority =
- resources.getString(
- R.string.lock_screen_preview_provider_authority,
- ),
- ),
- wallpaperInfoProvider = {
- suspendCancellableCoroutine { continuation ->
- injector
- .getCurrentWallpaperInfoFactory(context)
- .createCurrentWallpaperInfos(
- { homeWallpaper, lockWallpaper, _ ->
- continuation.resume(
- homeWallpaper ?: lockWallpaper,
- null,
- )
- },
- /* forceRefresh= */ true,
- )
- }
- },
- onWallpaperColorChanged = { colors ->
- colorViewModel.setLockWallpaperColors(colors)
- },
- initialExtrasProvider = {
- Bundle().apply {
- // Hide the clock from the system UI rendered preview so we can
- // place the carousel on top of it.
- putBoolean(
- ClockPreviewConstants.KEY_HIDE_CLOCK,
- true,
+ activity = activity,
+ previewView = lockScreenView,
+ viewModel =
+ ScreenPreviewViewModel(
+ previewUtils =
+ PreviewUtils(
+ context = context,
+ authority =
+ resources.getString(
+ R.string.lock_screen_preview_provider_authority,
+ ),
+ ),
+ wallpaperInfoProvider = {
+ suspendCancellableCoroutine { continuation ->
+ injector
+ .getCurrentWallpaperInfoFactory(context)
+ .createCurrentWallpaperInfos(
+ { homeWallpaper, lockWallpaper, _ ->
+ continuation.resume(
+ lockWallpaper ?: homeWallpaper,
+ null,
+ )
+ },
+ /* forceRefresh= */ true,
)
- }
- },
- ),
- lifecycleOwner = this,
- offsetToStart = displayUtils.isSingleDisplayOrUnfoldedHorizontalHinge(activity),
- )
- .show()
+ }
+ },
+ onWallpaperColorChanged = { colors ->
+ colorViewModel.setLockWallpaperColors(colors)
+ },
+ initialExtrasProvider = {
+ Bundle().apply {
+ // Hide the clock from the system UI rendered preview so we can
+ // place the carousel on top of it.
+ putBoolean(
+ ClockPreviewConstants.KEY_HIDE_CLOCK,
+ true,
+ )
+ }
+ },
+ ),
+ lifecycleOwner = this,
+ offsetToStart = displayUtils.isSingleDisplayOrUnfoldedHorizontalHinge(activity),
+ )
ClockSettingsBinder.bind(
view,
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
index 3eae7aa..a27d019 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -23,9 +23,9 @@
import android.widget.FrameLayout
import androidx.constraintlayout.helper.widget.Carousel
import androidx.constraintlayout.motion.widget.MotionLayout
-import androidx.core.view.get
import com.android.systemui.plugins.ClockController
import com.android.wallpaper.R
+import java.lang.Float.max
class ClockCarouselView(
context: Context,
@@ -36,11 +36,17 @@
attrs,
) {
+ var isCarouselInTransition = false
+
private val carousel: Carousel
private val motionLayout: MotionLayout
private lateinit var adapter: ClockCarouselAdapter
- private lateinit var scalingUpClock: ClockController
- private lateinit var scalingDownClock: ClockController
+ private lateinit var scalingUpClockController: ClockController
+ private lateinit var scalingDownClockController: ClockController
+ private var scalingUpClockView: View? = null
+ private var scalingDownClockView: View? = null
+ private var showingCardView: View? = null
+ private var hidingCardView: View? = null
init {
val clockCarousel = LayoutInflater.from(context).inflate(R.layout.clock_carousel, this)
@@ -65,13 +71,25 @@
startId: Int,
endId: Int
) {
+ isCarouselInTransition = true
val scalingDownClockId = adapter.clockIds[carousel.currentIndex]
val scalingUpIdx =
if (endId == R.id.next) (carousel.currentIndex + 1) % adapter.count()
else (carousel.currentIndex - 1 + adapter.count()) % adapter.count()
val scalingUpClockId = adapter.clockIds[scalingUpIdx]
- scalingDownClock = adapter.onGetClockController(scalingDownClockId)
- scalingUpClock = adapter.onGetClockController(scalingUpClockId)
+ scalingDownClockController = adapter.onGetClockController(scalingDownClockId)
+ scalingUpClockController = adapter.onGetClockController(scalingUpClockId)
+ scalingDownClockView = motionLayout?.findViewById(R.id.clock_scale_view_2)
+ scalingUpClockView =
+ motionLayout?.findViewById(
+ if (endId == R.id.next) R.id.clock_scale_view_3
+ else R.id.clock_scale_view_1
+ )
+ showingCardView = motionLayout?.findViewById(R.id.item_card_2)
+ hidingCardView =
+ motionLayout?.findViewById(
+ if (endId == R.id.next) R.id.item_card_3 else R.id.item_card_1
+ )
}
override fun onTransitionChange(
@@ -80,14 +98,27 @@
endId: Int,
progress: Float
) {
- scalingDownClock.animations.onPickerCarouselSwiping(
+ scalingDownClockController.animations.onPickerCarouselSwiping(
1 - progress,
getPreviewRatio()
)
- scalingUpClock.animations.onPickerCarouselSwiping(progress, getPreviewRatio())
+ scalingUpClockController.animations.onPickerCarouselSwiping(
+ progress,
+ getPreviewRatio()
+ )
+ val scalingUpScale = getScalingUpScale(progress)
+ val scalingDownScale = getScalingDownScale(progress)
+ scalingUpClockView?.scaleX = scalingUpScale
+ scalingUpClockView?.scaleY = scalingUpScale
+ scalingDownClockView?.scaleX = scalingDownScale
+ scalingDownClockView?.scaleY = scalingDownScale
+ showingCardView?.alpha = getShowingAlpha(progress)
+ hidingCardView?.alpha = getHidingAlpha(progress)
}
- override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {}
+ override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
+ isCarouselInTransition = false
+ }
override fun onTransitionTrigger(
motionLayout: MotionLayout?,
@@ -117,20 +148,37 @@
}
override fun populate(view: View?, index: Int) {
- val viewRoot = view as ViewGroup
- val clockHostView = viewRoot[0] as ViewGroup
+ val viewRoot = view as? ViewGroup ?: return
+ val cardView =
+ getClockCardViewId(viewRoot.id)?.let { viewRoot.findViewById(it) as? View }
+ ?: return
+ val clockScaleView =
+ getClockScaleViewId(viewRoot.id)?.let { viewRoot.findViewById(it) as? View }
+ ?: return
+ val clockHostView =
+ getClockHostViewId(viewRoot.id)?.let { viewRoot.findViewById(it) as? ViewGroup }
+ ?: return
+
clockHostView.removeAllViews()
val clockView = onGetClockController(clockIds[index]).largeClock.view
+ // Making sure the large clock tick to the correct time
+ onGetClockController(clockIds[index]).largeClock.events.onTimeTick()
// The clock view might still be attached to an existing parent. Detach before adding to
// another parent.
(clockView.parent as? ViewGroup)?.removeView(clockView)
clockHostView.addView(clockView)
// initialize scaling state for all clocks
- if (view.id != MIDDLE_VIEW_IN_START_STATE) {
+ if (!isMiddleView(viewRoot.id)) {
+ cardView.alpha = 1f
+ clockScaleView.scaleX = CLOCK_CAROUSEL_VIEW_SCALE
+ clockScaleView.scaleY = CLOCK_CAROUSEL_VIEW_SCALE
onGetClockController(clockIds[index])
.animations
.onPickerCarouselSwiping(0F, getPreviewRatio())
} else {
+ cardView.alpha = 0f
+ clockScaleView.scaleX = 1f
+ clockScaleView.scaleY = 1f
onGetClockController(clockIds[index])
.animations
.onPickerCarouselSwiping(1F, getPreviewRatio())
@@ -143,6 +191,56 @@
}
companion object {
- const val MIDDLE_VIEW_IN_START_STATE = R.id.item_view_2
+ const val CLOCK_CAROUSEL_VIEW_SCALE = 0.5f
+
+ fun getScalingUpScale(progress: Float) =
+ CLOCK_CAROUSEL_VIEW_SCALE + progress * (1f - CLOCK_CAROUSEL_VIEW_SCALE)
+
+ fun getScalingDownScale(progress: Float) = 1f - progress * (1f - CLOCK_CAROUSEL_VIEW_SCALE)
+
+ // This makes the card only starts to reveal in the last quarter of the trip so
+ // the card won't overlap the preview.
+ fun getShowingAlpha(progress: Float) = max(progress - 0.75f, 0f) * 4
+
+ // This makes the card starts to hide in the first quarter of the trip so the
+ // card won't overlap the preview.
+ fun getHidingAlpha(progress: Float) = max(1f - progress * 4, 0f)
+
+ fun getClockHostViewId(rootViewId: Int): Int? {
+ return when (rootViewId) {
+ R.id.item_view_0 -> R.id.clock_host_view_0
+ R.id.item_view_1 -> R.id.clock_host_view_1
+ R.id.item_view_2 -> R.id.clock_host_view_2
+ R.id.item_view_3 -> R.id.clock_host_view_3
+ R.id.item_view_4 -> R.id.clock_host_view_4
+ else -> null
+ }
+ }
+
+ fun getClockScaleViewId(rootViewId: Int): Int? {
+ return when (rootViewId) {
+ R.id.item_view_0 -> R.id.clock_scale_view_0
+ R.id.item_view_1 -> R.id.clock_scale_view_1
+ R.id.item_view_2 -> R.id.clock_scale_view_2
+ R.id.item_view_3 -> R.id.clock_scale_view_3
+ R.id.item_view_4 -> R.id.clock_scale_view_4
+ else -> null
+ }
+ }
+
+ fun getClockCardViewId(rootViewId: Int): Int? {
+ return when (rootViewId) {
+ R.id.item_view_0 -> R.id.item_card_0
+ R.id.item_view_1 -> R.id.item_card_1
+ R.id.item_view_2 -> R.id.item_card_2
+ R.id.item_view_3 -> R.id.item_card_3
+ R.id.item_view_4 -> R.id.item_card_4
+ else -> null
+ }
+ }
+
+ fun isMiddleView(rootViewId: Int): Boolean {
+ return rootViewId == R.id.item_view_2
+ }
}
}
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
index 67c7002..cf154d5 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
@@ -21,6 +21,7 @@
import androidx.annotation.ColorInt
import androidx.lifecycle.LifecycleOwner
import com.android.systemui.plugins.ClockController
+import com.android.systemui.plugins.WeatherData
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.wallpaper.R
import com.android.wallpaper.util.ScreenSizeCalculator
@@ -33,7 +34,7 @@
) {
private val timeTickListeners: ConcurrentHashMap<Int, TimeTicker> = ConcurrentHashMap()
private val clockControllers: HashMap<String, ClockController> = HashMap()
- private var ticker: TimeTicker? = null
+
fun getRatio(): Float {
val screenSizeCalculator = ScreenSizeCalculator.getInstance()
val screenSize = screenSizeCalculator.getScreenSize(activity.windowManager.defaultDisplay)
@@ -59,17 +60,34 @@
.onSeedColorChanged(seedColor)
}
+ fun updateTimeFormat(clockId: String) {
+ getController(clockId)
+ .events
+ .onTimeFormatChanged(android.text.format.DateFormat.is24HourFormat(activity))
+ }
+
fun registerTimeTicker(owner: LifecycleOwner) {
+ registerTimeTicker(owner, null)
+ }
+
+ fun registerTimeTicker(owner: LifecycleOwner, shouldTimeTick: (() -> Boolean)?) {
val hashCode = owner.hashCode()
if (timeTickListeners.keys.contains(hashCode)) {
return
}
+
timeTickListeners[hashCode] =
TimeTicker.registerNewReceiver(activity.applicationContext) {
- clockControllers.values.forEach { it.largeClock.events.onTimeTick() }
+ if (shouldTimeTick == null || shouldTimeTick()) {
+ onTimeTick()
+ }
}
}
+ private fun onTimeTick() {
+ clockControllers.values.forEach { it.largeClock.events.onTimeTick() }
+ }
+
fun unregisterTimeTicker(owner: LifecycleOwner) {
val hashCode = owner.hashCode()
timeTickListeners[hashCode]?.let {
@@ -94,7 +112,23 @@
activity.resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat() *
getRatio()
)
+ // Use placeholder for weather clock preview in picker
+ controller.events.onWeatherDataChanged(
+ WeatherData(
+ description = DESCRIPTION_PLACEHODLER,
+ state = WEATHERICON_PLACEHOLDER,
+ temperature = TEMPERATURE_PLACEHOLDER,
+ useCelsius = USE_CELSIUS_PLACEHODLER,
+ )
+ )
clockControllers[clockId] = controller
return controller
}
+
+ companion object {
+ val DESCRIPTION_PLACEHODLER = ""
+ val TEMPERATURE_PLACEHOLDER = 58
+ val WEATHERICON_PLACEHOLDER = WeatherData.WeatherStateIcon.MOSTLY_SUNNY
+ val USE_CELSIUS_PLACEHODLER = false
+ }
}
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
index 60a9e85..c01f56a 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
@@ -19,8 +19,6 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
@@ -44,14 +42,7 @@
val seedColor: Flow<Int?> = interactor.seedColor
- private val shouldShowCarousel = MutableStateFlow(false)
- val isCarouselVisible: Flow<Boolean> =
- combine(allClockIds.map { it.size > 1 }.distinctUntilChanged(), shouldShowCarousel) {
- hasMoreThanOneClock,
- shouldShowCarousel ->
- hasMoreThanOneClock && shouldShowCarousel
- }
- .distinctUntilChanged()
+ val isCarouselVisible: Flow<Boolean> = allClockIds.map { it.size > 1 }.distinctUntilChanged()
@OptIn(ExperimentalCoroutinesApi::class)
val selectedIndex: Flow<Int> =
@@ -69,14 +60,8 @@
.mapNotNull { it }
// Handle the case when there is only one clock in the carousel
- private val shouldShowSingleClock = MutableStateFlow(false)
val isSingleClockViewVisible: Flow<Boolean> =
- combine(allClockIds.map { it.size == 1 }.distinctUntilChanged(), shouldShowSingleClock) {
- hasOneClock,
- shouldShowSingleClock ->
- hasOneClock && shouldShowSingleClock
- }
- .distinctUntilChanged()
+ allClockIds.map { it.size == 1 }.distinctUntilChanged()
val clockId: Flow<String> =
allClockIds
@@ -87,11 +72,6 @@
interactor.setSelectedClock(clockId)
}
- fun showClockCarousel(shouldShow: Boolean) {
- shouldShowCarousel.value = shouldShow
- shouldShowSingleClock.value = shouldShow
- }
-
companion object {
const val CLOCKS_EVENT_UPDATE_DELAY_MILLIS: Long = 100
}
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
index 0303b41..43fb85b 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -22,7 +22,6 @@
import android.view.View
import android.view.ViewGroup
import android.view.ViewStub
-import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.android.customization.picker.clock.ui.binder.ClockCarouselViewBinder
@@ -46,7 +45,7 @@
class PreviewWithClockCarouselSectionController(
activity: Activity,
private val lifecycleOwner: LifecycleOwner,
- private val initialScreen: CustomizationSections.Screen,
+ private val screen: CustomizationSections.Screen,
wallpaperInfoFactory: CurrentWallpaperInfoFactory,
colorViewModel: WallpaperColorsViewModel,
displayUtils: DisplayUtils,
@@ -59,7 +58,7 @@
ScreenPreviewSectionController(
activity,
lifecycleOwner,
- initialScreen,
+ screen,
wallpaperInfoFactory,
colorViewModel,
displayUtils,
@@ -67,32 +66,31 @@
wallpaperInteractor,
) {
- private var clockCarouselBinding: ClockCarouselViewBinder.Binding? = null
private var clockColorAndSizeButton: View? = null
override val hideLockScreenClockPreview = true
override fun createView(context: Context): ScreenPreviewView {
val view = super.createView(context)
+ if (screen == CustomizationSections.Screen.LOCK_SCREEN) {
+ val clockColorAndSizeButtonStub: ViewStub =
+ view.requireViewById(R.id.clock_color_and_size_button)
+ clockColorAndSizeButtonStub.layoutResource = R.layout.clock_color_and_size_button
+ clockColorAndSizeButton = clockColorAndSizeButtonStub.inflate() as View
+ clockColorAndSizeButton?.setOnClickListener {
+ navigationController.navigateTo(ClockSettingsFragment())
+ }
- val clockColorAndSizeButtonStub: ViewStub =
- view.requireViewById(R.id.clock_color_and_size_button)
- clockColorAndSizeButtonStub.layoutResource = R.layout.clock_color_and_size_button
- clockColorAndSizeButton = clockColorAndSizeButtonStub.inflate() as View
- clockColorAndSizeButton?.setOnClickListener {
- navigationController.navigateTo(ClockSettingsFragment())
- }
+ val carouselViewStub: ViewStub = view.requireViewById(R.id.clock_carousel_view_stub)
+ carouselViewStub.layoutResource = R.layout.clock_carousel_view
+ val carouselView = carouselViewStub.inflate() as ClockCarouselView
- val carouselViewStub: ViewStub = view.requireViewById(R.id.clock_carousel_view_stub)
- carouselViewStub.layoutResource = R.layout.clock_carousel_view
- val carouselView = carouselViewStub.inflate() as ClockCarouselView
-
- // TODO (b/270716937) We should handle the single clock case in the clock carousel itself
- val singleClockViewStub: ViewStub = view.requireViewById(R.id.single_clock_view_stub)
- singleClockViewStub.layoutResource = R.layout.single_clock_view
- val singleClockView = singleClockViewStub.inflate() as ViewGroup
- lifecycleOwner.lifecycleScope.launch {
- clockCarouselBinding =
+ // TODO (b/270716937) We should handle the single clock case in the clock carousel
+ // itself
+ val singleClockViewStub: ViewStub = view.requireViewById(R.id.single_clock_view_stub)
+ singleClockViewStub.layoutResource = R.layout.single_clock_view
+ val singleClockView = singleClockViewStub.inflate() as ViewGroup
+ lifecycleOwner.lifecycleScope.launch {
ClockCarouselViewBinder.bind(
carouselView = carouselView,
singleClockView = singleClockView,
@@ -100,20 +98,9 @@
clockViewFactory = clockViewFactory,
lifecycleOwner = lifecycleOwner,
)
- onScreenSwitched(
- isOnLockScreen = initialScreen == CustomizationSections.Screen.LOCK_SCREEN
- )
+ }
}
- return view
- }
- override fun onScreenSwitched(isOnLockScreen: Boolean) {
- super.onScreenSwitched(isOnLockScreen)
- clockColorAndSizeButton?.isVisible = isOnLockScreen
- if (isOnLockScreen) {
- clockCarouselBinding?.show()
- } else {
- clockCarouselBinding?.hide()
- }
+ return view
}
}
diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
index 63f77bd..5bc7461 100644
--- a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
+++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
@@ -75,46 +75,22 @@
}
@Test
- fun setShouldShowCarousel() = runTest {
+ fun multipleClockCase() = runTest {
underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithMultipleClocks))
val observedIsCarouselVisible = collectLastValue(underTest.isCarouselVisible)
+ val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible)
advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
- underTest.showClockCarousel(false)
- assertThat(observedIsCarouselVisible()).isFalse()
- underTest.showClockCarousel(true)
assertThat(observedIsCarouselVisible()).isTrue()
+ assertThat(observedIsSingleClockViewVisible()).isFalse()
}
@Test
- fun shouldNotShowCarouselWhenSingleClock() = runTest {
+ fun singleClockCase() = runTest {
underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithSingleClock))
val observedIsCarouselVisible = collectLastValue(underTest.isCarouselVisible)
- advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
- underTest.showClockCarousel(false)
- assertThat(observedIsCarouselVisible()).isFalse()
- underTest.showClockCarousel(true)
- assertThat(observedIsCarouselVisible()).isFalse()
- }
-
- @Test
- fun setShouldShowSingleClock() = runTest {
- underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithSingleClock))
val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible)
advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
- underTest.showClockCarousel(false)
- assertThat(observedIsSingleClockViewVisible()).isFalse()
- underTest.showClockCarousel(true)
+ assertThat(observedIsCarouselVisible()).isFalse()
assertThat(observedIsSingleClockViewVisible()).isTrue()
}
-
- @Test
- fun shouldNotShowSingleClockWhenMultipleClocks() = runTest {
- underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithMultipleClocks))
- val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible)
- advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
- underTest.showClockCarousel(false)
- assertThat(observedIsSingleClockViewVisible()).isFalse()
- underTest.showClockCarousel(true)
- assertThat(observedIsSingleClockViewVisible()).isFalse()
- }
}