diff options
author | Setup Wizard Team <android-setup-team-eng@google.com> | 2021-04-23 18:20:17 +0800 |
---|---|---|
committer | Alex Li <alexylli@google.com> | 2021-04-26 07:03:03 +0000 |
commit | d94c19c2e8eaed91cc341dbcf95055f5877509c0 (patch) | |
tree | da704032bea332c0d656bcd63a81c6b1af59f005 /main | |
parent | f90b75b7aa320b0529babbab9332007a7e004631 (diff) | |
download | setupdesign-d94c19c2e8eaed91cc341dbcf95055f5877509c0.tar.gz |
Import updated Android Setupdesign Library 370048555
Copied from google3/third_party/java_src/android_libs/setupdesign
Test: mm
Bug: 186197285
Included changes:
- 370048555 [SetupDesign] Fixes if the activity not found the page wi...
- 369992582 [GlifLoadingLayout] Fix activity not finish when lottie f...
- 369792982 [ColorExtraction] Adds API that to get dynamic color.
PiperOrigin-RevId: 370048555
Change-Id: I9f64328511c89aa13d139c2bb1afcbed8d739e5d
Diffstat (limited to 'main')
30 files changed, 743 insertions, 120 deletions
diff --git a/main/res/layout-land-v31/sud_glif_blank_template_content.xml b/main/res/layout-land-v31/sud_glif_blank_template_content.xml index 9cd846d..dd4d52d 100644 --- a/main/res/layout-land-v31/sud_glif_blank_template_content.xml +++ b/main/res/layout-land-v31/sud_glif_blank_template_content.xml @@ -17,6 +17,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/layout-land-v31/sud_glif_list_template_content.xml b/main/res/layout-land-v31/sud_glif_list_template_content.xml index 6f6f20e..478ac5f 100644 --- a/main/res/layout-land-v31/sud_glif_list_template_content.xml +++ b/main/res/layout-land-v31/sud_glif_list_template_content.xml @@ -17,6 +17,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/layout-land-v31/sud_glif_preference_template_content.xml b/main/res/layout-land-v31/sud_glif_preference_template_content.xml index e3a2ba5..c03d2fe 100644 --- a/main/res/layout-land-v31/sud_glif_preference_template_content.xml +++ b/main/res/layout-land-v31/sud_glif_preference_template_content.xml @@ -17,6 +17,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/layout-land-v31/sud_glif_recycler_template_content.xml b/main/res/layout-land-v31/sud_glif_recycler_template_content.xml index d7d0985..4840caf 100644 --- a/main/res/layout-land-v31/sud_glif_recycler_template_content.xml +++ b/main/res/layout-land-v31/sud_glif_recycler_template_content.xml @@ -18,6 +18,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/layout-land-v31/sud_glif_template_content.xml b/main/res/layout-land-v31/sud_glif_template_content.xml index 5407be1..d1b6b92 100644 --- a/main/res/layout-land-v31/sud_glif_template_content.xml +++ b/main/res/layout-land-v31/sud_glif_template_content.xml @@ -17,6 +17,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/layout-v31/sud_glif_preference_template_content.xml b/main/res/layout-v31/sud_glif_preference_template_content.xml index dce2b83..c618139 100644 --- a/main/res/layout-v31/sud_glif_preference_template_content.xml +++ b/main/res/layout-v31/sud_glif_preference_template_content.xml @@ -17,10 +17,11 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/sud_glif_blank_template_content" /> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/main/res/layout/sud_content_info.xml b/main/res/layout/sud_content_info.xml new file mode 100644 index 0000000..288c3af --- /dev/null +++ b/main/res/layout/sud_content_info.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/sud_content_info_container" + style="@style/SudInfoContainer" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:baselineAligned="false" + android:orientation="horizontal"> + + <FrameLayout + android:id="@+id/sud_content_info_icon_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="top" + android:gravity="start"> + + <ImageView + android:id="@+id/sud_content_info_icon" + android:layout_width="@dimen/sud_content_info_icon_size" + android:layout_height="@dimen/sud_content_info_icon_size" + android:layout_marginEnd="@dimen/sud_content_info_icon_margin_end" + tools:ignore="ContentDescription" /> + + </FrameLayout> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_vertical" + android:orientation="vertical"> + + <com.google.android.setupdesign.view.RichTextView + android:id="@+id/sud_content_info_description" + style="@style/SudInfoDescription" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="start" + android:textAlignment="viewStart" + tools:ignore="UnusedAttribute" /> + + </LinearLayout> + +</LinearLayout> diff --git a/main/res/layout/sud_glif_blank_template_content.xml b/main/res/layout/sud_glif_blank_template_content.xml index 1eaae13..887655d 100644 --- a/main/res/layout/sud_glif_blank_template_content.xml +++ b/main/res/layout/sud_glif_blank_template_content.xml @@ -17,6 +17,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/layout/sud_glif_header.xml b/main/res/layout/sud_glif_header.xml index 564a5fe..50feeb2 100644 --- a/main/res/layout/sud_glif_header.xml +++ b/main/res/layout/sud_glif_header.xml @@ -22,13 +22,25 @@ android:layout_height="wrap_content" android:orientation="vertical"> - <ImageView - android:id="@+id/sud_layout_icon" - style="?attr/sudGlifIconStyle" - android:layout_width="wrap_content" + <FrameLayout + android:id="@+id/sud_layout_icon_container" + style="@style/SudGlifIconContainer" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:contentDescription="@null" - android:visibility="gone" /> + android:visibility="gone" > + <ImageView + android:id="@+id/sud_layout_icon" + style="?attr/sudGlifIconStyle" + android:layout_marginLeft="0dp" + android:layout_marginRight="0dp" + android:layout_marginTop="0dp" + android:layout_marginBottom="0dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:contentDescription="@null" + android:layout_gravity="?attr/sudGlifHeaderGravity" + android:visibility="gone" /> + </FrameLayout> <TextView android:id="@+id/suc_layout_title" diff --git a/main/res/layout/sud_glif_list_template_content.xml b/main/res/layout/sud_glif_list_template_content.xml index 1a6b4cd..09c56d2 100644 --- a/main/res/layout/sud_glif_list_template_content.xml +++ b/main/res/layout/sud_glif_list_template_content.xml @@ -18,6 +18,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/layout/sud_glif_recycler_template_content.xml b/main/res/layout/sud_glif_recycler_template_content.xml index 9ca640b..c2cccf0 100644 --- a/main/res/layout/sud_glif_recycler_template_content.xml +++ b/main/res/layout/sud_glif_recycler_template_content.xml @@ -19,6 +19,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/layout/sud_glif_template_content.xml b/main/res/layout/sud_glif_template_content.xml index 33dbe8c..fa898eb 100644 --- a/main/res/layout/sud_glif_template_content.xml +++ b/main/res/layout/sud_glif_template_content.xml @@ -18,6 +18,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/sud_layout_template_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> diff --git a/main/res/values-night/colors.xml b/main/res/values-night/colors.xml new file mode 100644 index 0000000..38f9bc2 --- /dev/null +++ b/main/res/values-night/colors.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + + <color name="system_primary_text">#FFFFFF</color> + <color name="system_secondary_text">#9AA0A6</color> + <color name="system_disable_option">#5F6368</color> + <color name="system_error_warning">#EE675C</color> + <color name="system_success_done">#5BB974</color> + <color name="system_fallback_accent">#669DF6</color> + <color name="system_accent_primary">@color/system_accent2_200</color> + +</resources>
\ No newline at end of file diff --git a/main/res/values-night/styles.xml b/main/res/values-night/styles.xml index ca94c12..d609b4c 100644 --- a/main/res/values-night/styles.xml +++ b/main/res/values-night/styles.xml @@ -22,5 +22,7 @@ <style name="SudThemeGlif.DayNight" parent="SudThemeGlif" /> <style name="SudThemeGlifV2.DayNight" parent="SudThemeGlifV2" /> <style name="SudThemeGlifV3.DayNight" parent="SudThemeGlifV3" /> + <style name="SudDynamicColorThemeGlifV3.DayNight" parent="SudDynamicColorThemeGlifV3" /> + <style name="SudFullDynamicColorThemeGlifV3.DayNight" parent="SudFullDynamicColorThemeGlifV3" /> </resources> diff --git a/main/res/values-v31/colors.xml b/main/res/values-v31/colors.xml new file mode 100644 index 0000000..03bc425 --- /dev/null +++ b/main/res/values-v31/colors.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <!-- Default color for BC --> + <color name="sud_color_accent_glif_v3_dark">#ff669df6</color> + <color name="sud_color_accent_glif_v3_light">#ff1a73e8</color> + + <!-- Accent color --> + <color name="sud_dynamic_color_accent_glif_v3_dark">@color/sud_system_accent2_300</color> + <color name="sud_dynamic_color_accent_glif_v3_light">@color/sud_system_accent2_500</color> + + <color name="sud_system_accent2_0">@android:color/system_accent2_0</color> + <color name="sud_system_accent2_50">@android:color/system_accent2_50</color> + <color name="sud_system_accent2_100">@android:color/system_accent2_100</color> + <color name="sud_system_accent2_200">@android:color/system_accent2_200</color> + <color name="sud_system_accent2_300">@android:color/system_accent2_300</color> + <color name="sud_system_accent2_400">@android:color/system_accent2_400</color> + <color name="sud_system_accent2_500">@android:color/system_accent2_500</color> + <color name="sud_system_accent2_600">@android:color/system_accent2_600</color> + <color name="sud_system_accent2_700">@android:color/system_accent2_700</color> + <color name="sud_system_accent2_800">@android:color/system_accent2_800</color> + <color name="sud_system_accent2_900">@android:color/system_accent2_900</color> + <color name="sud_system_accent2_1000">@android:color/system_accent2_1000</color> + + <color name="sud_system_primary_text">@color/system_primary_text</color> + <color name="sud_system_secondary_text">@color/system_secondary_text</color> + <color name="sud_system_disable_option">@color/system_disable_option</color> + <color name="sud_system_error_warning">@color/system_error_warning</color> + <color name="sud_system_success_done">@color/system_success_done</color> + <color name="sud_system_fallback_accent">@color/system_fallback_accent</color> + +</resources>
\ No newline at end of file diff --git a/main/res/values-v31/styles.xml b/main/res/values-v31/styles.xml new file mode 100644 index 0000000..a9fbade --- /dev/null +++ b/main/res/values-v31/styles.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <style name="SudDynamicColorThemeGlifV3" parent="SudThemeGlifV3"> + <item name="colorAccent">@color/sud_dynamic_color_accent_glif_v3_dark</item> + <item name="android:textColorLink">@color/sud_dynamic_color_accent_glif_v3_dark</item> + <item name="sucFullDynamicColor">false</item> + </style> + + <style name="SudDynamicColorThemeGlifV3.Light" parent="SudThemeGlifV3.Light"> + <item name="colorAccent">@color/sud_dynamic_color_accent_glif_v3_light</item> + <item name="android:textColorLink">@color/sud_dynamic_color_accent_glif_v3_light</item> + <item name="sucFullDynamicColor">false</item> + </style> + + <style name="SudFullDynamicColorThemeGlifV3" parent="SudDynamicColorThemeGlifV3"> + <item name="sucFullDynamicColor">true</item> + </style> + + <style name="SudFullDynamicColorThemeGlifV3.Light" parent="SudDynamicColorThemeGlifV3.Light"> + <item name="sucFullDynamicColor">true</item> + </style> +</resources>
\ No newline at end of file diff --git a/main/res/values/colors.xml b/main/res/values/colors.xml index 1becb87..736cd91 100644 --- a/main/res/values/colors.xml +++ b/main/res/values/colors.xml @@ -18,7 +18,6 @@ <resources> <!-- General colors --> - <color name="sud_color_accent_dark">#ff448aff</color> <color name="sud_color_accent_light">#ff3367d6</color> <color name="sud_color_background_dark">#ff303030</color> @@ -35,7 +34,6 @@ <color name="sud_flat_button_highlight">#1f000000</color> <!-- Navigation bar colors --> - <color name="sud_navbar_bg_dark">#ff21272b</color> <color name="sud_navbar_bg_light">#ffe4e7e9</color> @@ -59,7 +57,36 @@ <color name="sud_glif_window_bg_light_color">#ffffffff</color> <!-- Color for error text --> - <color name="sud_color_error_text_dark">#fff28b82</color> <!-- Google red 300 --> - <color name="sud_color_error_text_light">#ffd93025</color> <!-- Google red 600 --> + <color name="sud_color_error_text_dark">#fff28b82</color> + <color name="sud_color_error_text_light">#ffd93025</color> + + + <!-- Default color--> + <color name="sud_dynamic_color_accent_glif_v3_dark">@color/sud_color_accent_glif_v3_dark</color> + <color name="sud_dynamic_color_accent_glif_v3_light">@color/sud_color_accent_glif_v3_light</color> + + <color name="system_accent2_0">#ffffff</color> + <color name="system_accent2_50">#CDFAF1</color> + <color name="system_accent2_100">#BFEBE3</color> + <color name="system_accent2_200">#A4CFC7</color> + <color name="system_accent2_300">#89B4AC</color> + <color name="system_accent2_400">#6F9991</color> + <color name="system_accent2_500">#537C75</color> + <color name="system_accent2_600">#3D665F</color> + <color name="system_accent2_700">#254E47</color> + <color name="system_accent2_800">#0C3731</color> + <color name="system_accent2_900">#00211C</color> + <color name="system_accent2_1000">#000000</color> + + <color name="error_color_device_default_dark">#ec928e</color> + <color name="error_color_device_default_light">#b3261e</color> + + <color name="system_primary_text">#202124</color> + <color name="system_secondary_text">#5F6368</color> + <color name="system_disable_option">#DADCE0</color> + <color name="system_error_warning">#D93025</color> + <color name="system_success_done">#1E8E3E</color> + <color name="system_fallback_accent">#1A73E8</color> + <color name="system_accent_primary">@color/system_accent2_600</color> </resources> diff --git a/main/res/values/dimens.xml b/main/res/values/dimens.xml index 40fcc2a..4bbd079 100644 --- a/main/res/values/dimens.xml +++ b/main/res/values/dimens.xml @@ -75,6 +75,14 @@ <dimen name="sud_content_illustration_min_width">172dp</dimen> <dimen name="sud_content_illustration_padding_vertical">24dp</dimen> + <!-- Glif Content info text --> + <dimen name="sud_content_info_text_size">16sp</dimen> + <dimen name="sud_content_info_line_spacing_extra">3sp</dimen> + <dimen name="sud_content_info_icon_size">18dp</dimen> + <dimen name="sud_content_info_icon_margin_end">16dp</dimen> + <dimen name="sud_content_info_padding_top">0dp</dimen> + <dimen name="sud_content_info_padding_bottom">0dp</dimen> + <!-- Margin on the start to offset for margin in the drawable --> <dimen name="sud_radio_button_margin_start">-6dp</dimen> <dimen name="sud_radio_button_margin_top">0dp</dimen> diff --git a/main/res/values/styles.xml b/main/res/values/styles.xml index 70a81a8..2702359 100644 --- a/main/res/values/styles.xml +++ b/main/res/values/styles.xml @@ -296,6 +296,8 @@ <item name="sudButtonFontFamily">@string/sudFontSecondaryMedium</item> </style> <style name="SudThemeGlifV3" parent="SudBaseThemeGlifV3" /> + <style name="SudDynamicColorThemeGlifV3" parent="SudThemeGlifV3" /> + <style name="SudFullDynamicColorThemeGlifV3" parent="SudDynamicColorThemeGlifV3" /> <style name="SudBaseThemeGlifV3.Light" parent="SudThemeGlifV2.Light"> <item name="colorAccent">@color/sud_color_accent_glif_v3_light</item> @@ -307,6 +309,8 @@ <item name="sudButtonFontFamily">@string/sudFontSecondaryMedium</item> </style> <style name="SudThemeGlifV3.Light" parent="SudBaseThemeGlifV3.Light" /> + <style name="SudDynamicColorThemeGlifV3.Light" parent="SudThemeGlifV3.Light" /> + <style name="SudFullDynamicColorThemeGlifV3.Light" parent="SudDynamicColorThemeGlifV3.Light" /> <style name="Animation.SudWindowAnimation" parent="@android:style/Animation.Activity"> <item name="android:activityOpenEnterAnimation">@anim/sud_slide_next_in</item> @@ -320,6 +324,8 @@ <style name="SudThemeGlif.DayNight" parent="SudThemeGlif.Light" /> <style name="SudThemeGlifV2.DayNight" parent="SudThemeGlifV2.Light" /> <style name="SudThemeGlifV3.DayNight" parent="SudThemeGlifV3.Light" /> + <style name="SudDynamicColorThemeGlifV3.DayNight" parent="SudDynamicColorThemeGlifV3.Light" /> + <style name="SudFullDynamicColorThemeGlifV3.DayNight" parent="SudFullDynamicColorThemeGlifV3.Light" /> <!-- Content styles --> @@ -332,6 +338,18 @@ <item name="android:paddingBottom">?attr/sudContentFramePaddingBottom</item> </style> + <!-- Content info --> + + <style name="SudInfoContainer"> + <item name="android:paddingTop">@dimen/sud_content_info_padding_top</item> + <item name="android:paddingBottom">@dimen/sud_content_info_padding_bottom</item> + </style> + + <style name="SudInfoDescription"> + <item name="android:textSize">@dimen/sud_content_info_text_size</item> + <item name="android:lineSpacingExtra">@dimen/sud_content_info_line_spacing_extra</item> + </style> + <!-- Ignore UnusedResources: Used by clients --> <style name="SudDescription" tools:ignore="UnusedResources"> <!-- Before Honeycomb, layout_gravity is needed for FrameLayout to apply the margins --> @@ -665,6 +683,13 @@ <item name="android:layout_marginBottom">?attr/sucHeaderContainerMarginBottom</item> </style> + <style name="SudGlifIconContainer"> + <item name="android:layout_marginLeft">?attr/sudMarginStart</item> + <item name="android:layout_marginRight">?attr/sudMarginEnd</item> + <item name="android:layout_marginTop">?attr/sucGlifIconMarginTop</item> + <item name="android:maxHeight">?attr/sudGlifIconSize</item> + </style> + <style name="SudGlifIcon"> <item name="android:layout_marginLeft">?attr/sudMarginStart</item> <item name="android:layout_marginRight">?attr/sudMarginEnd</item> diff --git a/main/src/com/google/android/setupdesign/SetupWizardLayout.java b/main/src/com/google/android/setupdesign/SetupWizardLayout.java index 265bdf8..b91cec7 100644 --- a/main/src/com/google/android/setupdesign/SetupWizardLayout.java +++ b/main/src/com/google/android/setupdesign/SetupWizardLayout.java @@ -40,6 +40,7 @@ import android.widget.ScrollView; import android.widget.TextView; import com.google.android.setupcompat.internal.TemplateLayout; import com.google.android.setupcompat.template.SystemNavBarMixin; +import com.google.android.setupdesign.template.DescriptionMixin; import com.google.android.setupdesign.template.HeaderMixin; import com.google.android.setupdesign.template.NavigationBarMixin; import com.google.android.setupdesign.template.ProgressBarMixin; @@ -88,6 +89,7 @@ public class SetupWizardLayout extends TemplateLayout { registerMixin( HeaderMixin.class, new HeaderMixin(this, attrs, defStyleAttr)); + registerMixin(DescriptionMixin.class, new DescriptionMixin(this, attrs, defStyleAttr)); registerMixin(ProgressBarMixin.class, new ProgressBarMixin(this)); registerMixin(NavigationBarMixin.class, new NavigationBarMixin(this)); final RequireScrollMixin requireScrollMixin = new RequireScrollMixin(this); diff --git a/main/src/com/google/android/setupdesign/items/AbstractItemHierarchy.java b/main/src/com/google/android/setupdesign/items/AbstractItemHierarchy.java index 267e4ab..45c8e9e 100644 --- a/main/src/com/google/android/setupdesign/items/AbstractItemHierarchy.java +++ b/main/src/com/google/android/setupdesign/items/AbstractItemHierarchy.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; +import android.view.View; import com.google.android.setupdesign.R; import java.util.ArrayList; @@ -33,13 +34,13 @@ public abstract class AbstractItemHierarchy implements ItemHierarchy { /* non-static section */ private final ArrayList<Observer> observers = new ArrayList<>(); - private int id = 0; + private int id = View.NO_ID; public AbstractItemHierarchy() {} public AbstractItemHierarchy(Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SudAbstractItem); - id = a.getResourceId(R.styleable.SudAbstractItem_android_id, 0); + id = a.getResourceId(R.styleable.SudAbstractItem_android_id, View.NO_ID); a.recycle(); } diff --git a/main/src/com/google/android/setupdesign/template/IconMixin.java b/main/src/com/google/android/setupdesign/template/IconMixin.java index 964f712..1b2fbbf 100644 --- a/main/src/com/google/android/setupdesign/template/IconMixin.java +++ b/main/src/com/google/android/setupdesign/template/IconMixin.java @@ -25,6 +25,7 @@ import android.os.Build.VERSION_CODES; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup.LayoutParams; +import android.widget.FrameLayout; import android.widget.ImageView; import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; @@ -43,7 +44,7 @@ public class IconMixin implements Mixin { private final int originalHeight; private final ImageView.ScaleType originalScaleType; - + private final Context context; /** * A {@link com.google.android.setupcompat.template.Mixin} for setting and getting the Icon. * @@ -53,7 +54,7 @@ public class IconMixin implements Mixin { */ public IconMixin(TemplateLayout layout, AttributeSet attrs, int defStyleAttr) { templateLayout = layout; - final Context context = layout.getContext(); + context = layout.getContext(); ImageView iconView = getView(); if (iconView != null) { @@ -90,7 +91,7 @@ public class IconMixin implements Mixin { /** Tries to apply the partner customization to the header icon. */ public void tryApplyPartnerCustomizationStyle() { - HeaderAreaStyler.applyPartnerCustomizationIconStyle(getView(), templateLayout); + HeaderAreaStyler.applyPartnerCustomizationIconStyle(getView(), getContainerView()); } /** @@ -101,8 +102,14 @@ public class IconMixin implements Mixin { public void setIcon(Drawable icon) { final ImageView iconView = getView(); if (iconView != null) { + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + if (icon != null) { + icon.applyTheme(context.getTheme()); + } + } iconView.setImageDrawable(icon); iconView.setVisibility(icon != null ? View.VISIBLE : View.GONE); + setIconContainerVisibility(iconView.getVisibility()); } } @@ -118,6 +125,7 @@ public class IconMixin implements Mixin { // support lib users, which enables vector drawable compat to work on versions pre-L. iconView.setImageResource(icon); iconView.setVisibility(icon != 0 ? View.VISIBLE : View.GONE); + setIconContainerVisibility(iconView.getVisibility()); } } @@ -187,11 +195,23 @@ public class IconMixin implements Mixin { final ImageView iconView = getView(); if (iconView != null) { iconView.setVisibility(visibility); + setIconContainerVisibility(visibility); } } - /** @return The ImageView responsible for displaying the icon. */ + /** Returns the ImageView responsible for displaying the icon. */ protected ImageView getView() { return (ImageView) templateLayout.findManagedViewById(R.id.sud_layout_icon); } + + /** Returns the container of the ImageView responsible for displaying the icon. */ + protected FrameLayout getContainerView() { + return (FrameLayout) templateLayout.findManagedViewById(R.id.sud_layout_icon_container); + } + + private void setIconContainerVisibility(int visibility) { + if (getContainerView() != null) { + getContainerView().setVisibility(visibility); + } + } } diff --git a/main/src/com/google/android/setupdesign/transition/TransitionHelper.java b/main/src/com/google/android/setupdesign/transition/TransitionHelper.java index 0d76110..ec2c480 100644 --- a/main/src/com/google/android/setupdesign/transition/TransitionHelper.java +++ b/main/src/com/google/android/setupdesign/transition/TransitionHelper.java @@ -20,6 +20,7 @@ import android.annotation.TargetApi; import android.app.Activity; import android.app.ActivityOptions; import android.app.Fragment; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; @@ -31,11 +32,12 @@ import android.util.Log; import android.view.Window; import androidx.annotation.IntDef; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.google.android.material.transition.platform.MaterialSharedAxis; import com.google.android.setupcompat.partnerconfig.PartnerConfig; import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; +import com.google.android.setupcompat.util.BuildCompatUtils; import com.google.android.setupdesign.R; -import com.google.android.setupdesign.util.BuildCompatUtils; import com.google.android.setupdesign.util.ThemeHelper; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -140,6 +142,15 @@ public class TransitionHelper { */ public static final String EXTRA_ACTIVITY_OPTIONS = "sud:activity_options"; + /** A flag to avoid the {@link Activity#finish} been called more than once. */ + @VisibleForTesting static boolean isFinishCalled = false; + + /** A flag to avoid the {@link Activity#startActivity} called more than once. */ + @VisibleForTesting static boolean isStartActivity = false; + + /** A flag to avoid the {@link Activity#startActivityForResult} called more than once. */ + @VisibleForTesting static boolean isStartActivityForResult = false; + private TransitionHelper() {} /** @@ -382,52 +393,62 @@ public class TransitionHelper { + " task transitions"); } - if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS) { - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - if (activity.getWindow() != null - && !activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { - Log.w( - TAG, - "The transition won't take effect due to NO FEATURE_ACTIVITY_TRANSITIONS feature"); - } + if (!isStartActivity) { + isStartActivity = true; + if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS) { + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + if (activity.getWindow() != null + && !activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { + Log.w( + TAG, + "The transition won't take effect due to NO FEATURE_ACTIVITY_TRANSITIONS feature"); + } - Bundle bundleActivityOptions; - if (overrideActivityOptions != null) { - bundleActivityOptions = overrideActivityOptions; + Bundle bundleActivityOptions; + if (overrideActivityOptions != null) { + bundleActivityOptions = overrideActivityOptions; + } else { + bundleActivityOptions = makeActivityOptions(activity, intent); + } + intent.putExtra(EXTRA_ACTIVITY_OPTIONS, (Parcelable) bundleActivityOptions); + activity.startActivity(intent, bundleActivityOptions); } else { - bundleActivityOptions = makeActivityOptions(activity, intent); + Log.w( + TAG, + "Fallback to using startActivity due to the" + + " ActivityOptions#makeSceneTransitionAnimation is supported from Android Sdk " + + VERSION_CODES.LOLLIPOP); + startActivityWithTransitionInternal(activity, intent, overrideActivityOptions); } - intent.putExtra(EXTRA_ACTIVITY_OPTIONS, (Parcelable) bundleActivityOptions); - activity.startActivity(intent, bundleActivityOptions); } else { - Log.w( - TAG, - "Fallback to using startActivity due to the" - + " ActivityOptions#makeSceneTransitionAnimation is supported from Android Sdk " - + VERSION_CODES.LOLLIPOP); startActivityWithTransitionInternal(activity, intent, overrideActivityOptions); } - } else { - startActivityWithTransitionInternal(activity, intent, overrideActivityOptions); } + isStartActivity = false; } private static void startActivityWithTransitionInternal( Activity activity, Intent intent, Bundle overrideActivityOptions) { - if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { - if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS - && overrideActivityOptions != null) { - activity.startActivity(intent, overrideActivityOptions); + try { + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { + if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS + && overrideActivityOptions != null) { + activity.startActivity(intent, overrideActivityOptions); + } else { + activity.startActivity(intent); + } } else { + Log.w( + TAG, + "Fallback to using startActivity(Intent) due to the startActivity(Intent, Bundle) is" + + " supported from Android Sdk " + + VERSION_CODES.JELLY_BEAN); activity.startActivity(intent); } - } else { - Log.w( - TAG, - "Fallback to using startActivity(Intent) due to the startActivity(Intent, Bundle) is" - + " supported from Android Sdk " - + VERSION_CODES.JELLY_BEAN); - activity.startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.w(TAG, "Activity not found when startActivity with transition."); + isStartActivity = false; + throw e; } } @@ -462,54 +483,64 @@ public class TransitionHelper { + " task transitions"); } - if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS) { - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - if (activity.getWindow() != null - && !activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { - Log.w( - TAG, - "The transition won't take effect due to NO FEATURE_ACTIVITY_TRANSITIONS feature"); - } + if (!isStartActivityForResult) { + isStartActivityForResult = true; + if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS) { + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + if (activity.getWindow() != null + && !activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { + Log.w( + TAG, + "The transition won't take effect due to NO FEATURE_ACTIVITY_TRANSITIONS feature"); + } - Bundle bundleActivityOptions; - if (overrideActivityOptions != null) { - bundleActivityOptions = overrideActivityOptions; + Bundle bundleActivityOptions; + if (overrideActivityOptions != null) { + bundleActivityOptions = overrideActivityOptions; + } else { + bundleActivityOptions = makeActivityOptions(activity, intent); + } + intent.putExtra(EXTRA_ACTIVITY_OPTIONS, (Parcelable) bundleActivityOptions); + activity.startActivityForResult(intent, requestCode, bundleActivityOptions); } else { - bundleActivityOptions = makeActivityOptions(activity, intent); + Log.w( + TAG, + "Fallback to using startActivityForResult API due to the" + + " ActivityOptions#makeSceneTransitionAnimation is supported from Android Sdk " + + VERSION_CODES.LOLLIPOP); + startActivityForResultWithTransitionInternal( + activity, intent, requestCode, overrideActivityOptions); } - intent.putExtra(EXTRA_ACTIVITY_OPTIONS, (Parcelable) bundleActivityOptions); - activity.startActivityForResult(intent, requestCode, bundleActivityOptions); } else { - Log.w( - TAG, - "Fallback to using startActivityForResult API due to the" - + " ActivityOptions#makeSceneTransitionAnimation is supported from Android Sdk " - + VERSION_CODES.LOLLIPOP); startActivityForResultWithTransitionInternal( activity, intent, requestCode, overrideActivityOptions); } - } else { - startActivityForResultWithTransitionInternal( - activity, intent, requestCode, overrideActivityOptions); + isStartActivityForResult = false; } } private static void startActivityForResultWithTransitionInternal( Activity activity, Intent intent, int requestCode, Bundle overrideActivityOptions) { - if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { - if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS - && overrideActivityOptions != null) { - activity.startActivityForResult(intent, requestCode, overrideActivityOptions); + try { + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { + if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS + && overrideActivityOptions != null) { + activity.startActivityForResult(intent, requestCode, overrideActivityOptions); + } else { + activity.startActivityForResult(intent, requestCode); + } } else { + Log.w( + TAG, + "Fallback to using startActivityForResult(Intent) due to the" + + " startActivityForResult(Intent,int) is supported from Android Sdk " + + VERSION_CODES.JELLY_BEAN); activity.startActivityForResult(intent, requestCode); } - } else { - Log.w( - TAG, - "Fallback to using startActivityForResult(Intent) due to the" - + " startActivityForResult(Intent,int) is supported from Android Sdk " - + VERSION_CODES.JELLY_BEAN); - activity.startActivityForResult(intent, requestCode); + } catch (ActivityNotFoundException e) { + Log.w(TAG, "Activity not found when startActivityForResult with transition."); + isStartActivityForResult = false; + throw e; } } @@ -524,17 +555,22 @@ public class TransitionHelper { throw new IllegalArgumentException("Invalid activity=" + activity); } - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP - && getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS) { - activity.finishAfterTransition(); - } else { - Log.w( - TAG, - "Fallback to using Activity#finish() due to the" - + " Activity#finishAfterTransition() is supported from Android Sdk " - + VERSION_CODES.LOLLIPOP); - activity.finish(); + // Avoids finish been called more than once. + if (!isFinishCalled) { + isFinishCalled = true; + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP + && getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS) { + activity.finishAfterTransition(); + } else { + Log.w( + TAG, + "Fallback to using Activity#finish() due to the" + + " Activity#finishAfterTransition() is supported from Android Sdk " + + VERSION_CODES.LOLLIPOP); + activity.finish(); + } } + isFinishCalled = false; } /** @@ -552,9 +588,51 @@ public class TransitionHelper { * A wrapper method, create a {@link Bundle} from {@link ActivityOptions} to transition between * Activities using cross-Activity scene animations. This {@link Bundle} that can be used with * {@link Context#startActivity(Intent, Bundle)} and related methods. + * + * <p>Example usage: + * + * <pre>{@code + * Intent intent = new Intent("com.example.NEXT_ACTIVITY"); + * activity.startActivity(intent, TransitionHelper.makeActivityOptions(activity, intent, null); + * }</pre> + * + * <p>Unexpected usage: + * + * <pre>{@code + * Intent intent = new Intent("com.example.NEXT_ACTIVITY"); + * Intent intent2 = new Intent("com.example.NEXT_ACTIVITY"); + * activity.startActivity(intent, TransitionHelper.makeActivityOptions(activity, intent2, null); + * }</pre> */ @Nullable public static Bundle makeActivityOptions(Activity activity, Intent intent) { + return makeActivityOptions(activity, intent, false); + } + + /** + * A wrapper method, create a {@link Bundle} from {@link ActivityOptions} to transition between + * Activities using cross-Activity scene animations. This {@link Bundle} that can be used with + * {@link Context#startActivity(Intent, Bundle)} and related methods. When this {@code activity} + * is a no UI activity(the activity doesn't inflate any layouts), you will need to pass the bundle + * coming from previous UI activity as the {@link ActivityOptions}, otherwise, the transition + * won't be take effect. The {@code overrideActivityOptionsFromIntent} is supporting this purpose + * to return the {@link ActivityOptions} instead of creating from this no UI activity while the + * transition is apply {@link #CONFIG_TRANSITION_SHARED_X_AXIS} config. Moreover, the + * startActivity*WithTransition relative methods and {@link #makeActivityOptions} will put {@link + * ActivityOptions} to the {@code intent} by default, you can get the {@link ActivityOptions} + * which makes from previous activity by accessing {@link #EXTRA_ACTIVITY_OPTIONS} extra from + * {@link Activity#getIntent()}. + * + * <p>Example usage of a no UI activity: + * + * <pre>{@code + * Intent intent = new Intent("com.example.NEXT_ACTIVITY"); + * activity.startActivity(intent, TransitionHelper.makeActivityOptions(activity, intent, true); + * }</pre> + */ + @Nullable + public static Bundle makeActivityOptions( + Activity activity, Intent intent, boolean overrideActivityOptionsFromIntent) { Bundle resultBundle = null; if (activity == null || intent == null) { return resultBundle; @@ -576,7 +654,11 @@ public class TransitionHelper { "The transition won't take effect due to NO FEATURE_ACTIVITY_TRANSITIONS feature"); } - resultBundle = ActivityOptions.makeSceneTransitionAnimation(activity).toBundle(); + if (overrideActivityOptionsFromIntent && activity.getIntent() != null) { + resultBundle = activity.getIntent().getBundleExtra(EXTRA_ACTIVITY_OPTIONS); + } else { + resultBundle = ActivityOptions.makeSceneTransitionAnimation(activity).toBundle(); + } intent.putExtra(EXTRA_ACTIVITY_OPTIONS, (Parcelable) resultBundle); return resultBundle; } diff --git a/main/src/com/google/android/setupdesign/util/BuildCompatUtils.java b/main/src/com/google/android/setupdesign/util/BuildCompatUtils.java index 7174455..524b9a2 100644 --- a/main/src/com/google/android/setupdesign/util/BuildCompatUtils.java +++ b/main/src/com/google/android/setupdesign/util/BuildCompatUtils.java @@ -21,7 +21,10 @@ import android.os.Build; /** * An util class to check whether the current OS version is higher or equal to sdk version of * device. + * + * @deprecated Uses {@link com.google.android.setupcompat.util.BuildCompatUtils} instead. */ +@Deprecated public final class BuildCompatUtils { /** diff --git a/main/src/com/google/android/setupdesign/util/ContentStyler.java b/main/src/com/google/android/setupdesign/util/ContentStyler.java index 2ab1658..d390780 100644 --- a/main/src/com/google/android/setupdesign/util/ContentStyler.java +++ b/main/src/com/google/android/setupdesign/util/ContentStyler.java @@ -17,10 +17,19 @@ package com.google.android.setupdesign.util; import android.content.Context; +import android.os.Build; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; import android.widget.TextView; +import androidx.annotation.Nullable; import com.google.android.setupcompat.partnerconfig.PartnerConfig; import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; +import com.google.android.setupdesign.R; import com.google.android.setupdesign.util.TextViewPartnerStyler.TextPartnerConfigs; import java.util.Locale; @@ -48,7 +57,144 @@ public final class ContentStyler { ContentStyler.getPartnerContentTextGravity(contentText.getContext()))); } - public static int getPartnerContentTextGravity(Context context) { + /** + * Applies the partner heavy style of content info to the given views including content info + * container, content info icon and content info text, the given views should be included in a + * layout which the same view hierarchy with {@link R.layout#sud_content_info}. + * + * @param infoContainer A view the container resource of content info + * @param infoIcon A image view the icon resource of content info + * @param infoText A text view content info resource + */ + public static void applyInfoPartnerCustomizationStyle( + @Nullable View infoContainer, @Nullable ImageView infoIcon, TextView infoText) { + if (!PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(infoText)) { + return; + } + + Context context = infoText.getContext(); + + boolean textSizeConfigAvailable = + PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_INFO_TEXT_SIZE); + boolean fontFamilyConfigAvailable = + PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_INFO_FONT_FAMILY); + + TextViewPartnerStyler.applyPartnerCustomizationStyle( + infoText, + new TextPartnerConfigs( + null, + null, + textSizeConfigAvailable ? PartnerConfig.CONFIG_CONTENT_INFO_TEXT_SIZE : null, + fontFamilyConfigAvailable ? PartnerConfig.CONFIG_CONTENT_INFO_FONT_FAMILY : null, + null, + null, + 0)); + + // TODO: Move CONFIG_CONTENT_INFO_LINE_SPACING_EXTRA to TextPartnerConfigs for + // customize + boolean isAtLeastP = VERSION.SDK_INT >= VERSION_CODES.P; + if (isAtLeastP + && PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_INFO_LINE_SPACING_EXTRA)) { + int textLineSpacingExtraInPx = + (int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_CONTENT_INFO_LINE_SPACING_EXTRA); + + float infoTextSizeInPx = infoText.getTextSize(); + if (textSizeConfigAvailable) { + float textSizeInPx = + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_CONTENT_INFO_TEXT_SIZE, 0); + if (textSizeInPx > 0) { + infoTextSizeInPx = textSizeInPx; + } + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + infoText.setLineHeight(Math.round(textLineSpacingExtraInPx + infoTextSizeInPx)); + } + } + + if (infoIcon != null) { + ViewGroup.LayoutParams lp = infoIcon.getLayoutParams(); + + if (PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_INFO_ICON_SIZE)) { + int oldHeight = lp.height; + lp.height = + (int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_CONTENT_INFO_ICON_SIZE); + lp.width = lp.width * (lp.height / oldHeight); + infoIcon.setScaleType(ScaleType.FIT_CENTER); + } + + boolean partnerConfigAvailable = + PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_INFO_ICON_MARGIN_END); + if (partnerConfigAvailable && lp instanceof ViewGroup.MarginLayoutParams) { + final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) lp; + int endMargin = + (int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_CONTENT_INFO_ICON_MARGIN_END); + mlp.setMargins(mlp.leftMargin, mlp.topMargin, endMargin, mlp.bottomMargin); + } + } + + if (infoContainer != null) { + float paddingTop; + if (PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_INFO_PADDING_TOP)) { + paddingTop = + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_CONTENT_INFO_PADDING_TOP); + } else { + paddingTop = infoContainer.getPaddingTop(); + } + + float paddingBottom; + if (PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_INFO_PADDING_BOTTOM)) { + paddingBottom = + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_CONTENT_INFO_PADDING_BOTTOM); + } else { + paddingBottom = infoContainer.getPaddingBottom(); + } + + if (paddingTop != infoContainer.getPaddingTop() + || paddingBottom != infoContainer.getPaddingBottom()) { + infoContainer.setPadding(0, (int) paddingTop, 0, (int) paddingBottom); + } + } + } + + /** + * Returns the layout margin start from partner config. If the activity of given {@code context} + * does not enable the partner heavy theme, then returns the default value from GlifTheme. + * + * @param context The context of a GlifLayout activity. + */ + public static float getPartnerContentMarginStart(Context context) { + // default value is GlifTheme layout margin start. + // That is the attr sudMarginStart, and the value is sud_layout_margin_sides. + float result = context.getResources().getDimension(R.dimen.sud_layout_margin_sides); + if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(context)) { + if (PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_START)) { + result = + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_LAYOUT_MARGIN_START, result); + } + } + return result; + } + + private static int getPartnerContentTextGravity(Context context) { String gravity = PartnerConfigHelper.get(context) .getString(context, PartnerConfig.CONFIG_CONTENT_LAYOUT_GRAVITY); diff --git a/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java b/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java new file mode 100644 index 0000000..6d3a932 --- /dev/null +++ b/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.setupdesign.util; + +import android.content.Context; +import androidx.annotation.ColorInt; +import androidx.annotation.VisibleForTesting; +import com.google.android.setupdesign.R; + +/** The class to get dynamic colors. */ +public final class DynamicColorPalette { + + @VisibleForTesting static int colorRes = 0; + + private DynamicColorPalette() {} + + /** Dynamic color category. */ + public enum DynamicColorCategory { + PRIMARY_TEXT, + SECONDARY_TEXT, + DISABLED_OPTION, + ERROR_WARNING, + SUCCESS_DONE, + FALLBACK_ACCENT + } + + @ColorInt + public static int getColor(Context context, DynamicColorCategory dynamicColorCategory) { + switch (dynamicColorCategory) { + case PRIMARY_TEXT: + colorRes = R.color.sud_system_primary_text; + break; + case SECONDARY_TEXT: + colorRes = R.color.sud_system_secondary_text; + break; + case DISABLED_OPTION: + colorRes = R.color.sud_system_disable_option; + break; + case ERROR_WARNING: + colorRes = R.color.sud_system_error_warning; + break; + case SUCCESS_DONE: + colorRes = R.color.sud_system_success_done; + break; + case FALLBACK_ACCENT: + colorRes = R.color.sud_system_fallback_accent; + break; + // fall out + } + + return context.getResources().getColor(colorRes); + } +} diff --git a/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java b/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java index 33a4d34..44a7d49 100644 --- a/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java +++ b/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java @@ -16,24 +16,24 @@ package com.google.android.setupdesign.util; -import static com.google.android.setupdesign.util.BuildCompatUtils.isAtLeastS; +import static com.google.android.setupcompat.util.BuildCompatUtils.isAtLeastS; import android.content.Context; import android.graphics.drawable.VectorDrawable; import android.os.Build; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; import android.util.Log; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewTreeObserver; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ImageView.ScaleType; -import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; -import com.google.android.setupcompat.internal.TemplateLayout; import com.google.android.setupcompat.partnerconfig.PartnerConfig; import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; import com.google.android.setupdesign.util.TextViewPartnerStyler.TextPartnerConfigs; @@ -48,7 +48,7 @@ public final class HeaderAreaStyler { @VisibleForTesting static final String WARN_TO_USE_DRAWABLE = - "To achieve scaling icon in SetupDesign lib, should use vector drawable icon!!"; + "To achieve scaling icon in SetupDesign lib, should use vector drawable icon from "; /** * Applies the partner heavy style of header text to the given textView {@code header}. @@ -184,23 +184,23 @@ public final class HeaderAreaStyler { * partner heavy theme first, and then the partner icon size would be applied. * * @param iconImage A ImageView would apply the partner style of header icon - * @param templateLayout The template containing this mixin + * @param iconContainer The container of the header icon */ public static void applyPartnerCustomizationIconStyle( - @Nullable ImageView iconImage, TemplateLayout templateLayout) { - if (iconImage == null) { + @Nullable ImageView iconImage, FrameLayout iconContainer) { + if (iconImage == null || iconContainer == null) { return; } - if (PartnerStyleHelper.shouldApplyPartnerResource(templateLayout)) { + if (PartnerStyleHelper.shouldApplyPartnerResource(iconImage)) { Context context = iconImage.getContext(); int gravity = PartnerStyleHelper.getLayoutGravity(context); if (gravity != 0) { setGravity(iconImage, gravity); } - if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(iconImage)) { - final ViewGroup.LayoutParams lp = iconImage.getLayoutParams(); + if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(iconContainer)) { + final ViewGroup.LayoutParams lp = iconContainer.getLayoutParams(); boolean partnerConfigAvailable = PartnerConfigHelper.get(context) .isPartnerConfigAvailable(PartnerConfig.CONFIG_ICON_MARGIN_TOP); @@ -218,11 +218,12 @@ public final class HeaderAreaStyler { checkImageType(iconImage); - lp.height = + final ViewGroup.LayoutParams lpIcon = iconImage.getLayoutParams(); + lpIcon.height = (int) PartnerConfigHelper.get(context) .getDimension(context, PartnerConfig.CONFIG_ICON_SIZE); - lp.width = LayoutParams.WRAP_CONTENT; + lpIcon.width = LayoutParams.WRAP_CONTENT; iconImage.setScaleType(ScaleType.FIT_CENTER); } } @@ -239,13 +240,11 @@ public final class HeaderAreaStyler { // TODO: Remove when Partners all used Drawable icon image and never use if (isAtLeastS() && !(imageView.getDrawable() == null - || imageView.getDrawable() instanceof VectorDrawable - || imageView.getDrawable() instanceof VectorDrawableCompat)) { - if (Build.TYPE.equals("userdebug") || Build.TYPE.equals("eng")) { - Toast.makeText(imageView.getContext(), WARN_TO_USE_DRAWABLE, Toast.LENGTH_LONG) - .show(); - } - Log.w(TAG, WARN_TO_USE_DRAWABLE); + || (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP + && imageView.getDrawable() instanceof VectorDrawable) + || imageView.getDrawable() instanceof VectorDrawableCompat) + && (Build.TYPE.equals("userdebug") || Build.TYPE.equals("eng"))) { + Log.w(TAG, WARN_TO_USE_DRAWABLE + imageView.getContext().getPackageName()); } return true; } @@ -253,8 +252,8 @@ public final class HeaderAreaStyler { } private static void setGravity(ImageView icon, int gravity) { - if (icon.getLayoutParams() instanceof LinearLayout.LayoutParams) { - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) icon.getLayoutParams(); + if (icon.getLayoutParams() instanceof FrameLayout.LayoutParams) { + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) icon.getLayoutParams(); layoutParams.gravity = gravity; icon.setLayoutParams(layoutParams); } diff --git a/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java b/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java index ed5af71..2cde29e 100644 --- a/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java +++ b/main/src/com/google/android/setupdesign/util/PartnerStyleHelper.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.content.Context; import android.content.res.TypedArray; import android.os.Build; +import androidx.annotation.NonNull; import android.view.Gravity; import android.view.View; import com.google.android.setupcompat.PartnerCustomizationLayout; @@ -35,7 +36,7 @@ import java.util.Locale; public final class PartnerStyleHelper { /** - * Returns the partner configuration of layout gravity, usually apply to wigets in header area. + * Returns the partner configuration of layout gravity, usually apply to widgets in header area. */ public static int getLayoutGravity(Context context) { String gravity = @@ -119,6 +120,39 @@ public final class PartnerStyleHelper { return isSetupFlow || usePartnerResource; } + /** Returns {@code true} if the dynamic color is set. */ + static boolean trySetDynamicColor(@NonNull Context context, boolean isDayNightEnabled) { + if (!PartnerConfigHelper.shouldApplyDynamicColor(context)) { + return false; + } + + Activity activity = null; + try { + activity = PartnerCustomizationLayout.lookupActivityFromContext(context); + } catch (IllegalArgumentException ex) { + return false; + } + + // try best to get partner resource settings from attrs + boolean isSetupFlow = WizardManagerHelper.isAnySetupWizard(activity.getIntent()); + + if (isSetupFlow) { + // apply theme for inside setup flow + activity.setTheme( + isDayNightEnabled + ? R.style.SudDynamicColorThemeGlifV3_DayNight + : R.style.SudDynamicColorThemeGlifV3_Light); + } else { + // apply theme for outside setup flow + activity.setTheme( + isDayNightEnabled + ? R.style.SudFullDynamicColorThemeGlifV3_DayNight + : R.style.SudFullDynamicColorThemeGlifV3_Light); + } + + return true; + } + /** * Returns if the current layout/activity applies heavy partner customized configurations or not. * @@ -134,7 +168,7 @@ public final class PartnerStyleHelper { return shouldApplyPartnerHeavyThemeResource(view.getContext()); } - private static boolean shouldApplyPartnerHeavyThemeResource(Context context) { + static boolean shouldApplyPartnerHeavyThemeResource(Context context) { try { Activity activity = PartnerCustomizationLayout.lookupActivityFromContext(context); TemplateLayout layout = findLayoutFromActivity(activity); diff --git a/main/src/com/google/android/setupdesign/util/ThemeHelper.java b/main/src/com/google/android/setupdesign/util/ThemeHelper.java index 7f29c5d..6852aa4 100644 --- a/main/src/com/google/android/setupdesign/util/ThemeHelper.java +++ b/main/src/com/google/android/setupdesign/util/ThemeHelper.java @@ -158,5 +158,16 @@ public final class ThemeHelper { return PartnerConfigHelper.shouldApplyExtendedPartnerConfig(context); } + /** Returns {@code true} if the partner provider of SetupWizard is ready to dynamic color. */ + public static boolean shouldApplyDynamicColor(@NonNull Context context) { + return PartnerConfigHelper.shouldApplyDynamicColor(context); + } + + /** Returns {@code true} if the dynamic color is set. */ + public static boolean trySetDynamicColor(@NonNull Context context) { + return shouldApplyExtendedPartnerConfig(context) + && PartnerStyleHelper.trySetDynamicColor(context, isSetupWizardDayNightEnabled(context)); + } + private ThemeHelper() {} } diff --git a/main/src/com/google/android/setupdesign/view/IllustrationVideoView.java b/main/src/com/google/android/setupdesign/view/IllustrationVideoView.java index 7f6449d..de71f7c 100644 --- a/main/src/com/google/android/setupdesign/view/IllustrationVideoView.java +++ b/main/src/com/google/android/setupdesign/view/IllustrationVideoView.java @@ -37,8 +37,8 @@ import android.view.View; import androidx.annotation.Nullable; import androidx.annotation.RawRes; import androidx.annotation.VisibleForTesting; +import com.google.android.setupcompat.util.BuildCompatUtils; import com.google.android.setupdesign.R; -import com.google.android.setupdesign.util.BuildCompatUtils; import java.io.IOException; /** |