diff options
author | Xin Li <delphij@google.com> | 2022-02-11 06:57:33 +0000 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2022-02-11 06:57:33 +0000 |
commit | 6a549883438cb1f702aba42a4cd1674cacdf3057 (patch) | |
tree | df8acaea4c3a8188d68f26c09e036981054664a4 | |
parent | 6fe04f365351fb1d797f51912ed45c56c1303da5 (diff) | |
parent | 42cf94b997ba62fb320c0662772e5c38f7e3a982 (diff) | |
download | setupdesign-6a549883438cb1f702aba42a4cd1674cacdf3057.tar.gz |
Merge sc-v2-dev-plus-aosp-without-vendor@8084891sam_222710654
Bug: 214455710
Merged-In: I2017c021e6baf200ad718eb661010eba56cdf39d
Change-Id: Icfc14be2b731e4958e090bb935807ee414076b7f
63 files changed, 1375 insertions, 344 deletions
diff --git a/exempting_lint_checks.txt b/exempting_lint_checks.txt index 201fd64..b6d4d30 100644 --- a/exempting_lint_checks.txt +++ b/exempting_lint_checks.txt @@ -47,3 +47,19 @@ third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupd third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/NavigationBar.java: ResourceType: @StyleableRes int colorForeground = 1; third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/StickyHeaderListView.java: CustomViewStyleable: .obtainStyledAttributes(attrs, R.styleable.SudStickyHeaderListView, defStyleAttr, 0); third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/StickyHeaderScrollView.java: ObsoleteSdkInt: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/GlifLayout.java: CustomViewStyleable: getContext().obtainStyledAttributes(attrs, R.styleable.SudGlifLayout, defStyleAttr, 0); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/SetupWizardLayout.java: CustomViewStyleable: .obtainStyledAttributes(attrs, R.styleable.SudSetupWizardLayout, defStyleAttr, 0); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/items/RecyclerItemAdapter.java: NotifyDataSetChanged: notifyDataSetChanged(); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/util/Partner.java: DiscouragedApi: return resources.getIdentifier(name, defType, packageName); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/FillContentLayout.java: CustomViewStyleable: context.obtainStyledAttributes(attrs, R.styleable.SudFillContentLayout, defStyleAttr, 0); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/HeaderRecyclerView.java: CustomViewStyleable: .obtainStyledAttributes(attrs, R.styleable.SudHeaderRecyclerView, defStyleAttr, 0); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/HeaderRecyclerView.java: NotifyDataSetChanged: notifyDataSetChanged(); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/IconUniformityAppImageView.java: AnnotateVersionCheck: private static final boolean ON_L_PLUS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/Illustration.java: CustomViewStyleable: getContext().obtainStyledAttributes(attrs, R.styleable.SudIllustration, defStyleAttr, 0); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/IllustrationVideoView.java: CustomViewStyleable: context.obtainStyledAttributes(attrs, R.styleable.SudIllustrationVideoView); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/IntrinsicSizeFrameLayout.java: CustomViewStyleable: attrs, R.styleable.SudIntrinsicSizeFrameLayout, defStyleAttr, 0); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/NavigationBar.java: ResourceType: @StyleableRes int colorBackground = 2; +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/NavigationBar.java: ResourceType: @StyleableRes int colorForeground = 1; +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/RichTextView.java: DiscouragedApi: .getIdentifier(textAppearance, "style", context.getPackageName()); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/StickyHeaderListView.java: CustomViewStyleable: .obtainStyledAttributes(attrs, R.styleable.SudStickyHeaderListView, defStyleAttr, 0); +third_party/java_src/android_libs/setupdesign/main/src/com/google/android/setupdesign/view/StickyHeaderScrollView.java: ObsoleteSdkInt: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { diff --git a/lottie_loading_layout/AndroidManifest.xml b/lottie_loading_layout/AndroidManifest.xml index 3cf1948..67c363d 100644 --- a/lottie_loading_layout/AndroidManifest.xml +++ b/lottie_loading_layout/AndroidManifest.xml @@ -20,6 +20,6 @@ <uses-sdk android:minSdkVersion="14" - android:targetSdkVersion="30" /> + android:targetSdkVersion="31" /> </manifest> diff --git a/lottie_loading_layout/res/layout-sw600dp-land-v31/sud_glif_fullscreen_loading_template_content.xml b/lottie_loading_layout/res/layout-sw600dp-land-v31/sud_glif_fullscreen_loading_template_content.xml new file mode 100644 index 0000000..df88e0b --- /dev/null +++ b/lottie_loading_layout/res/layout-sw600dp-land-v31/sud_glif_fullscreen_loading_template_content.xml @@ -0,0 +1,103 @@ +<?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. +--> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ViewStub + android:id="@+id/sud_loading_layout_lottie_stub" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:inflatedId="@+id/sud_layout_lottie_illustration" + android:layout="@layout/sud_loading_fullscreen_lottie_layout" /> + + <LinearLayout + android:id="@+id/sud_layout_template_content" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="horizontal"> + + <LinearLayout + android:id="@+id/sud_landscape_header_area" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="@dimen/sud_glif_land_header_area_weight" + android:orientation="vertical"> + + <ViewStub + android:id="@+id/sud_layout_sticky_header" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <com.google.android.setupdesign.view.BottomScrollView + android:id="@+id/sud_header_scroll_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fillViewport="true" + android:scrollIndicators="?attr/sudScrollIndicators"> + + <include layout="@layout/sud_glif_header" /> + + </com.google.android.setupdesign.view.BottomScrollView> + + </LinearLayout> + + <LinearLayout + android:id="@+id/sud_landscape_content_area" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="@dimen/sud_glif_land_content_area_weight" + android:orientation="vertical"> + + <FrameLayout + android:id="@+id/sud_layout_loading_content" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ViewStub + android:id="@+id/sud_loading_layout_illustration_stub" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:inflatedId="@+id/sud_layout_progress_illustration" + android:layout="@layout/sud_loading_illustration_layout" /> + + <FrameLayout + android:id="@+id/sud_layout_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" /> + + </FrameLayout> + + </LinearLayout> + + </LinearLayout> + + <ViewStub + android:id="@+id/suc_layout_footer" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </LinearLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/lottie_loading_layout/res/layout-sw600dp-v31/sud_glif_fullscreen_loading_template_card.xml b/lottie_loading_layout/res/layout-sw600dp-v31/sud_glif_fullscreen_loading_template_card.xml new file mode 100644 index 0000000..8cd6af2 --- /dev/null +++ b/lottie_loading_layout/res/layout-sw600dp-v31/sud_glif_fullscreen_loading_template_card.xml @@ -0,0 +1,49 @@ +<?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" + android:id="@+id/suc_layout_status" + style="@style/SudGlifCardBackground" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true" + android:gravity="center_horizontal" + android:orientation="vertical"> + + <View + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" + android:visibility="invisible" /> + + <com.google.android.setupdesign.view.IntrinsicSizeFrameLayout + style="@style/SudGlifCardContainer" + android:layout_width="@dimen/sud_glif_card_width" + android:layout_height="wrap_content" + android:height="@dimen/sud_glif_card_height"> + + <include layout="@layout/sud_glif_fullscreen_loading_template_content" /> + + </com.google.android.setupdesign.view.IntrinsicSizeFrameLayout> + + <View + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" + android:visibility="invisible" /> + +</LinearLayout> diff --git a/lottie_loading_layout/res/layout-sw600dp-v31/sud_glif_fullscreen_loading_template_content.xml b/lottie_loading_layout/res/layout-sw600dp-v31/sud_glif_fullscreen_loading_template_content.xml new file mode 100644 index 0000000..97f86be --- /dev/null +++ b/lottie_loading_layout/res/layout-sw600dp-v31/sud_glif_fullscreen_loading_template_content.xml @@ -0,0 +1,96 @@ +<?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. +--> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ViewStub + android:id="@+id/sud_loading_layout_lottie_stub" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:inflatedId="@+id/sud_layout_lottie_illustration" + android:layout="@layout/sud_loading_fullscreen_lottie_layout" /> + + <LinearLayout + android:id="@+id/sud_layout_template_content" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <ViewStub + android:id="@+id/sud_layout_sticky_header" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <!-- Ignore UnusedAttribute: scrollIndicators is new in M. Default to no indicators in older + versions. --> + <com.google.android.setupdesign.view.BottomScrollView + android:id="@+id/sud_header_scroll_view" + android:layout_width="match_parent" + android:layout_height="?attr/sudLoadingHeaderHeight" + android:fillViewport="true" + android:scrollIndicators="?attr/sudScrollIndicators" + tools:ignore="UnusedAttribute"> + + <include layout="@layout/sud_glif_header" /> + + </com.google.android.setupdesign.view.BottomScrollView> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <ViewStub + android:id="@+id/sud_loading_layout_illustration_stub" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:inflatedId="@+id/sud_layout_progress_illustration" + android:layout="@layout/sud_loading_illustration_layout" /> + + <FrameLayout + android:id="@+id/sud_layout_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" /> + + </LinearLayout> + + </LinearLayout> + + </LinearLayout> + + <ViewStub + android:id="@+id/suc_layout_footer" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </LinearLayout> + +</FrameLayout> diff --git a/lottie_loading_layout/res/layout-sw600dp-v31/sud_loading_fullscreen_lottie_layout.xml b/lottie_loading_layout/res/layout-sw600dp-v31/sud_loading_fullscreen_lottie_layout.xml new file mode 100644 index 0000000..8c98e74 --- /dev/null +++ b/lottie_loading_layout/res/layout-sw600dp-v31/sud_loading_fullscreen_lottie_layout.xml @@ -0,0 +1,34 @@ +<?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:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.airbnb.lottie.LottieAnimationView + android:id="@+id/sud_lottie_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:importantForAccessibility="no" + android:layout_gravity="start|bottom" + android:scaleType="fitStart" + app:lottie_autoPlay="false" + app:lottie_loop="true" /> + +</LinearLayout> diff --git a/lottie_loading_layout/res/layout-v31/sud_glif_loading_template_content.xml b/lottie_loading_layout/res/layout-v31/sud_glif_loading_template_content.xml index 8415324..c5d36ef 100644 --- a/lottie_loading_layout/res/layout-v31/sud_glif_loading_template_content.xml +++ b/lottie_loading_layout/res/layout-v31/sud_glif_loading_template_content.xml @@ -89,4 +89,4 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/lottie_loading_layout/res/layout/sud_glif_loading_template_compat.xml b/lottie_loading_layout/res/layout/sud_glif_loading_template_compat.xml index 86003b9..d8e9177 100644 --- a/lottie_loading_layout/res/layout/sud_glif_loading_template_compat.xml +++ b/lottie_loading_layout/res/layout/sud_glif_loading_template_compat.xml @@ -23,4 +23,4 @@ <include layout="@layout/sud_glif_loading_template_content" /> -</com.google.android.setupcompat.view.StatusBarBackgroundLayout>
\ No newline at end of file +</com.google.android.setupcompat.view.StatusBarBackgroundLayout> diff --git a/lottie_loading_layout/res/values-sw600dp-v31/layouts.xml b/lottie_loading_layout/res/values-sw600dp-v31/layouts.xml new file mode 100644 index 0000000..f627c06 --- /dev/null +++ b/lottie_loading_layout/res/values-sw600dp-v31/layouts.xml @@ -0,0 +1,21 @@ +<?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 xmlns:tools="http://schemas.android.com/tools"> + <item name="sud_glif_loading_template" type="layout" tools:ignore="UnusedResources">@layout/sud_glif_loading_template_card</item> + <item name="sud_glif_fullscreen_loading_template" type="layout" tools:ignore="UnusedResources">@layout/sud_glif_fullscreen_loading_template_card</item> +</resources> diff --git a/lottie_loading_layout/res/values/layouts.xml b/lottie_loading_layout/res/values/layouts.xml index 483f09d..9ea5e67 100644 --- a/lottie_loading_layout/res/values/layouts.xml +++ b/lottie_loading_layout/res/values/layouts.xml @@ -17,4 +17,5 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <item name="sud_glif_loading_template" type="layout" tools:ignore="UnusedResources">@layout/sud_glif_loading_template_compat</item> + <item name="sud_glif_fullscreen_loading_template" type="layout" tools:ignore="UnusedResources">@layout/sud_glif_loading_template_compat</item> </resources>
\ No newline at end of file diff --git a/lottie_loading_layout/src/com/google/android/setupdesign/GlifLoadingLayout.java b/lottie_loading_layout/src/com/google/android/setupdesign/GlifLoadingLayout.java index d239e3d..7874b75 100644 --- a/lottie_loading_layout/src/com/google/android/setupdesign/GlifLoadingLayout.java +++ b/lottie_loading_layout/src/com/google/android/setupdesign/GlifLoadingLayout.java @@ -30,9 +30,7 @@ import android.graphics.ColorFilter; import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.provider.Settings.Global; +import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.AttributeSet; import android.util.Log; @@ -63,6 +61,7 @@ import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.util.BuildCompatUtils; import com.google.android.setupdesign.lottieloadinglayout.R; import com.google.android.setupdesign.view.IllustrationVideoView; +import com.google.android.setupdesign.util.LayoutStyler; import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -90,6 +89,11 @@ public class GlifLoadingLayout extends GlifLayout { @VisibleForTesting Map<KeyPath, SimpleColorFilter> customizationMap = new HashMap<>(); + private AnimatorListener animatorListener; + private Runnable nextActionRunnable; + private boolean workFinished; + @VisibleForTesting public boolean runRunnable; + @VisibleForTesting public List<LottieAnimationFinishListener> animationFinishListeners = new ArrayList<>(); @@ -125,8 +129,6 @@ public class GlifLoadingLayout extends GlifLayout { .obtainStyledAttributes(attrs, R.styleable.SudGlifLoadingLayout, defStyleAttr, 0); customLottieResource = a.getResourceId(R.styleable.SudGlifLoadingLayout_sudLottieRes, 0); String illustrationType = a.getString(R.styleable.SudGlifLoadingLayout_sudIllustrationType); - boolean usePartnerHeavyTheme = - a.getBoolean(R.styleable.SudGlifLoadingLayout_sudUsePartnerHeavyTheme, false); a.recycle(); if (customLottieResource != 0) { @@ -145,16 +147,54 @@ public class GlifLoadingLayout extends GlifLayout { } } - boolean applyPartnerHeavyThemeResource = shouldApplyPartnerResource() && usePartnerHeavyTheme; - if (applyPartnerHeavyThemeResource) { - View view = findManagedViewById(R.id.sud_layout_loading_content); - if (view != null) { - applyPartnerCustomizationContentPaddingTopStyle(view); + View view = findManagedViewById(R.id.sud_layout_loading_content); + if (view != null) { + if (shouldApplyPartnerResource()) { + LayoutStyler.applyPartnerCustomizationExtraPaddingStyle(view); } + tryApplyPartnerCustomizationContentPaddingTopStyle(view); } updateHeaderHeight(); updateLandscapeMiddleHorizontalSpacing(); + + workFinished = false; + runRunnable = true; + + LottieAnimationView lottieAnimationView = findLottieAnimationView(); + if (lottieAnimationView != null) { + /* + * add the listener used to log animation end and check whether the + * work in background finish when repeated. + */ + animatorListener = + new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + // Do nothing. + } + + @Override + public void onAnimationEnd(Animator animation) { + Log.i(TAG, "Animate enable:" + isAnimateEnable() + ". Animation end."); + } + + @Override + public void onAnimationCancel(Animator animation) { + // Do nothing. + } + + @Override + public void onAnimationRepeat(Animator animation) { + if (workFinished) { + Log.i(TAG, "Animation repeat but work finished, run the register runnable."); + finishRunnable(nextActionRunnable); + workFinished = false; + } + } + }; + lottieAnimationView.addAnimatorListener(animatorListener); + } } @Override @@ -166,6 +206,21 @@ public class GlifLoadingLayout extends GlifLayout { } } + private boolean isAnimateEnable() { + try { + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { + return Settings.Global.getFloat( + getContext().getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE) + != 0f; + } else { + return true; + } + + } catch (SettingNotFoundException e) { + return true; + } + } + public void setIllustrationType(@IllustrationType String type) { if (customLottieResource != 0) { throw new IllegalStateException( @@ -251,7 +306,7 @@ public class GlifLoadingLayout extends GlifLayout { if (activity == null) { throw new NullPointerException("activity should not be null"); } - registerAnimationFinishRunnable(activity::finish, /* allowFinishWithMaximumDuration= */ true); + registerAnimationFinishRunnable(activity::finish); } /** @@ -289,8 +344,7 @@ public class GlifLoadingLayout extends GlifLayout { if (finish) { activity.finish(); } - }, - /* allowFinishWithMaximumDuration= */ true); + }); } /** @@ -332,8 +386,7 @@ public class GlifLoadingLayout extends GlifLayout { if (finish) { activity.finish(); } - }, - /* allowFinishWithMaximumDuration= */ true); + }); } private void updateHeaderHeight() { @@ -407,7 +460,7 @@ public class GlifLoadingLayout extends GlifLayout { linearLayout.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); } - private static final int getButtonContainerHeight(View view) { + private static int getButtonContainerHeight(View view) { view.measure( MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(), MeasureSpec.EXACTLY)); @@ -612,7 +665,8 @@ public class GlifLoadingLayout extends GlifLayout { String[] splitItem = item.split(":"); if (splitItem.length == 2) { customizationMap.put( - new KeyPath(splitItem[0]), new SimpleColorFilter(Color.parseColor(splitItem[1]))); + new KeyPath("**", splitItem[0], "**"), + new SimpleColorFilter(Color.parseColor(splitItem[1]))); } else { Log.w(TAG, "incorrect format customization, value=" + item); } @@ -647,7 +701,17 @@ public class GlifLoadingLayout extends GlifLayout { @Override protected View onInflateTemplate(LayoutInflater inflater, int template) { if (template == 0) { - template = R.layout.sud_glif_loading_template; + boolean useFullScreenIllustration = + PartnerConfigHelper.get(getContext()) + .getBoolean( + getContext(), + PartnerConfig.CONFIG_LOADING_LAYOUT_FULL_SCREEN_ILLUSTRATION_ENABLED, + false); + if (useFullScreenIllustration) { + template = R.layout.sud_glif_fullscreen_loading_template; + } else { + template = R.layout.sud_glif_loading_template; + } } return inflateTemplate(inflater, R.style.SudThemeGlif_Light, template); } @@ -727,38 +791,31 @@ public class GlifLoadingLayout extends GlifLayout { } /** - * Register the {@link Runnable} as a callback class that will be perform when animation finished. + * Register the {@link Runnable} as a callback that will be performed when the animation finished. */ public void registerAnimationFinishRunnable(Runnable runnable) { - registerAnimationFinishRunnable(runnable, /* allowFinishWithMaximumDuration= */ false); + workFinished = true; + nextActionRunnable = runnable; + synchronized (this) { + runRunnable = true; + animationFinishListeners.add( + new LottieAnimationFinishListener(this, () -> finishRunnable(runnable))); + } } - /** - * Register the {@link Runnable} as a callback class that will be perform when animation finished. - * {@code allowFinishWithMaximumDuration} to allow the animation finish advanced by {@link - * PartnerConfig#CONFIG_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS} config. The {@code runnable} - * will be performed if the Lottie animation finish played and the duration of Lottie animation - * less than @link PartnerConfig#CONFIG_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS} config. - */ - public void registerAnimationFinishRunnable( - Runnable runnable, boolean allowFinishWithMaximumDuration) { - if (allowFinishWithMaximumDuration) { - int delayMs = - PartnerConfigHelper.get(getContext()) - .getInteger( - getContext(), PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_DISPLAY_MINIMUM_MS, 0); - animationFinishListeners.add(new LottieAnimationFinishListener(this, runnable, delayMs)); - } else { - animationFinishListeners.add( - new LottieAnimationFinishListener(this, runnable, /* finishWithMinimumDuration= */ 0L)); + @VisibleForTesting + public synchronized void finishRunnable(Runnable runnable) { + // to avoid run the runnable twice. + if (runRunnable) { + runnable.run(); } + runRunnable = false; } /** The listener that to indicate the playing status for lottie animation. */ @VisibleForTesting public static class LottieAnimationFinishListener { - private final Handler handler; private final Runnable runnable; private final GlifLoadingLayout glifLoadingLayout; private final LottieAnimationView lottieAnimationView; @@ -788,22 +845,21 @@ public class GlifLoadingLayout extends GlifLayout { }; @VisibleForTesting - LottieAnimationFinishListener( - GlifLoadingLayout glifLoadingLayout, Runnable runnable, long finishWithMinimumDuration) { + LottieAnimationFinishListener(GlifLoadingLayout glifLoadingLayout, Runnable runnable) { if (runnable == null) { throw new NullPointerException("Runnable can not be null"); } this.glifLoadingLayout = glifLoadingLayout; this.runnable = runnable; - this.handler = new Handler(Looper.getMainLooper()); this.lottieAnimationView = glifLoadingLayout.findLottieAnimationView(); - if (glifLoadingLayout.isLottieLayoutVisible() && !isZeroAnimatorDurationScale()) { - lottieAnimationView.setRepeatCount(0); + // TODO: add test case for verify the case which isAnimating returns true. + if (glifLoadingLayout.isLottieLayoutVisible() + && lottieAnimationView.isAnimating() + && !isZeroAnimatorDurationScale()) { + Log.i(TAG, "Register animation finish."); lottieAnimationView.addAnimatorListener(animatorListener); - if (finishWithMinimumDuration > 0) { - handler.postDelayed(this::onAnimationFinished, finishWithMinimumDuration); - } + lottieAnimationView.setRepeatCount(0); } else { onAnimationFinished(); } @@ -813,8 +869,9 @@ public class GlifLoadingLayout extends GlifLayout { boolean isZeroAnimatorDurationScale() { try { if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { - return Global.getFloat( - glifLoadingLayout.getContext().getContentResolver(), Global.ANIMATOR_DURATION_SCALE) + return Settings.Global.getFloat( + glifLoadingLayout.getContext().getContentResolver(), + Settings.Global.ANIMATOR_DURATION_SCALE) == 0f; } else { return false; @@ -827,7 +884,6 @@ public class GlifLoadingLayout extends GlifLayout { @VisibleForTesting public void onAnimationFinished() { - handler.removeCallbacks(runnable); runnable.run(); if (lottieAnimationView != null) { lottieAnimationView.removeAnimatorListener(animatorListener); diff --git a/main/res/anim-ldrtl-v31/sud_interpolator.xml b/main/res/anim-ldrtl-v31/sud_interpolator.xml new file mode 100644 index 0000000..bec77f0 --- /dev/null +++ b/main/res/anim-ldrtl-v31/sud_interpolator.xml @@ -0,0 +1,19 @@ +<?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. +--> + +<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1" /> diff --git a/main/res/anim-ldrtl-v31/sud_slide_back_in.xml b/main/res/anim-ldrtl-v31/sud_slide_back_in.xml new file mode 100644 index 0000000..006d9b4 --- /dev/null +++ b/main/res/anim-ldrtl-v31/sud_slide_back_in.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<translate xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="@integer/sudTransitionDuration" + android:fromXDelta="100%" + android:toXDelta="0%" + android:interpolator="@anim/sud_interpolator" /> diff --git a/main/res/anim-ldrtl-v31/sud_slide_back_out.xml b/main/res/anim-ldrtl-v31/sud_slide_back_out.xml new file mode 100644 index 0000000..341bbad --- /dev/null +++ b/main/res/anim-ldrtl-v31/sud_slide_back_out.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<translate xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="@integer/sudTransitionDuration" + android:fromXDelta="0%" + android:toXDelta="-100%" + android:interpolator="@anim/sud_interpolator" /> diff --git a/main/res/anim-ldrtl-v31/sud_slide_next_in.xml b/main/res/anim-ldrtl-v31/sud_slide_next_in.xml new file mode 100644 index 0000000..77d4cd5 --- /dev/null +++ b/main/res/anim-ldrtl-v31/sud_slide_next_in.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<translate xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="@integer/sudTransitionDuration" + android:fromXDelta="-100%" + android:toXDelta="0%" + android:interpolator="@anim/sud_interpolator" /> diff --git a/main/res/anim-ldrtl-v31/sud_slide_next_out.xml b/main/res/anim-ldrtl-v31/sud_slide_next_out.xml new file mode 100644 index 0000000..8ae16d4 --- /dev/null +++ b/main/res/anim-ldrtl-v31/sud_slide_next_out.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<translate xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="@integer/sudTransitionDuration" + android:fromXDelta="0%" + android:toXDelta="100%" + android:interpolator="@anim/sud_interpolator" /> diff --git a/main/res/color-v31/sud_dynamic_switch_track_off_light.xml b/main/res/color-v31/sud_dynamic_switch_track_off_light.xml new file mode 100644 index 0000000..fc9cc97 --- /dev/null +++ b/main/res/color-v31/sud_dynamic_switch_track_off_light.xml @@ -0,0 +1,19 @@ +<?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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@android:color/system_neutral2_500" android:lStar="45" /> +</selector>
\ No newline at end of file diff --git a/main/res/color-v31/sud_dynamic_switch_track_on_dark.xml b/main/res/color-v31/sud_dynamic_switch_track_on_dark.xml new file mode 100644 index 0000000..b8997f9 --- /dev/null +++ b/main/res/color-v31/sud_dynamic_switch_track_on_dark.xml @@ -0,0 +1,19 @@ +<?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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@android:color/system_accent2_500" android:lStar="51" /> +</selector>
\ No newline at end of file diff --git a/main/res/color/sud_switch_thumb_off.xml b/main/res/color/sud_switch_thumb_off.xml new file mode 100644 index 0000000..8e54c8c --- /dev/null +++ b/main/res/color/sud_switch_thumb_off.xml @@ -0,0 +1,23 @@ +<?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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> + <item android:state_enabled="false" + android:color="?attr/sudSwitchBarThumbOffColor" + android:alpha="?android:attr/disabledAlpha" /> + <item android:color="?attr/sudSwitchBarThumbOffColor" /> +</selector>
\ No newline at end of file diff --git a/main/res/color/sud_switch_thumb_on.xml b/main/res/color/sud_switch_thumb_on.xml new file mode 100644 index 0000000..494c179 --- /dev/null +++ b/main/res/color/sud_switch_thumb_on.xml @@ -0,0 +1,23 @@ +<?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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> + <item android:state_enabled="false" + android:color="?attr/sudSwitchBarThumbOnColor" + android:alpha="?android:attr/disabledAlpha" /> + <item android:color="?attr/sudSwitchBarThumbOnColor" /> +</selector>
\ No newline at end of file diff --git a/main/res/color/sud_switch_track_off.xml b/main/res/color/sud_switch_track_off.xml new file mode 100644 index 0000000..4770393 --- /dev/null +++ b/main/res/color/sud_switch_track_off.xml @@ -0,0 +1,23 @@ +<?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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> + <item android:state_enabled="false" + android:color="?attr/sudSwitchBarTrackOffColor" + android:alpha="?android:attr/disabledAlpha" /> + <item android:color="?attr/sudSwitchBarTrackOffColor" /> +</selector> diff --git a/main/res/color/sud_switch_track_on.xml b/main/res/color/sud_switch_track_on.xml index a95a1ee..fb93f05 100644 --- a/main/res/color/sud_switch_track_on.xml +++ b/main/res/color/sud_switch_track_on.xml @@ -17,10 +17,7 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <item android:state_enabled="false" - android:color="?android:attr/colorForeground" + android:color="?attr/sudSwitchBarTrackOnColor" android:alpha="?android:attr/disabledAlpha" /> - <item android:state_checked="true" - android:color="?android:attr/colorControlActivated" tools:ignore="NewApi" - android:alpha="?android:attr/disabledAlpha" /> - <item android:color="?android:attr/colorForeground" /> + <item android:color="?attr/sudSwitchBarTrackOnColor" /> </selector> diff --git a/main/res/drawable-v21/sud_switch_thumb_on.xml b/main/res/drawable-v21/sud_switch_thumb_on.xml deleted file mode 100644 index 224f181..0000000 --- a/main/res/drawable-v21/sud_switch_thumb_on.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?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. - --> - -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:top="@dimen/sud_switch_thumb_margin" - android:left="@dimen/sud_switch_thumb_margin" - android:right="@dimen/sud_switch_thumb_margin" - android:bottom="@dimen/sud_switch_thumb_margin"> - <shape android:shape="oval"> - <size - android:height="@dimen/sud_switch_thumb_size" - android:width="@dimen/sud_switch_thumb_size" /> - <solid android:color="?android:attr/colorControlActivated" /> - </shape> - </item> -</layer-list>
\ No newline at end of file diff --git a/main/res/drawable/sud_switch_thumb_on.xml b/main/res/drawable/sud_switch_thumb_on.xml index cc1cf06..d4dad6f 100644 --- a/main/res/drawable/sud_switch_thumb_on.xml +++ b/main/res/drawable/sud_switch_thumb_on.xml @@ -26,7 +26,7 @@ <size android:height="@dimen/sud_switch_thumb_size" android:width="@dimen/sud_switch_thumb_size" /> - <solid android:color="?android:attr/colorAccent" tools:ignore="NewApi" /> + <solid android:color="@color/sud_switch_thumb_on" /> </shape> </item> </layer-list> 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 dd4d52d..fd7cbd2 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 @@ -47,6 +47,7 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="@dimen/sud_glif_land_content_area_weight" + android:focusedByDefault="true" android:orientation="vertical"> <FrameLayout 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 478ac5f..f7a353b 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 @@ -58,6 +58,7 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="@dimen/sud_glif_land_content_area_weight" + android:focusedByDefault="true" android:orientation="vertical"> <com.google.android.setupdesign.view.StickyHeaderListView 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 c03d2fe..fcb9ff6 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 @@ -58,6 +58,7 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="@dimen/sud_glif_land_content_area_weight" + android:focusedByDefault="true" android:orientation="vertical"> <FrameLayout 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 4840caf..4bd56ea 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 @@ -59,6 +59,7 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="@dimen/sud_glif_land_content_area_weight" + android:focusedByDefault="true" android:orientation="vertical"> <com.google.android.setupdesign.view.HeaderRecyclerView 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 d1b6b92..1e8f9a0 100644 --- a/main/res/layout-land-v31/sud_glif_template_content.xml +++ b/main/res/layout-land-v31/sud_glif_template_content.xml @@ -58,6 +58,7 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="@dimen/sud_glif_land_content_area_weight" + android:focusedByDefault="true" android:orientation="vertical"> <com.google.android.setupdesign.view.BottomScrollView @@ -65,7 +66,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" - android:scrollIndicators="?attr/sudScrollIndicators"> + android:scrollIndicators="?attr/sudScrollIndicators" + android:importantForAccessibility="no"> <LinearLayout android:layout_width="match_parent" diff --git a/main/res/layout-sw600dp-v31/sud_glif_preference_template_card.xml b/main/res/layout-sw600dp-v31/sud_glif_preference_template_card.xml new file mode 100644 index 0000000..68ea99e --- /dev/null +++ b/main/res/layout-sw600dp-v31/sud_glif_preference_template_card.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/suc_layout_status" + style="@style/SudGlifCardBackground" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true" + android:gravity="center_horizontal" + android:orientation="vertical"> + + <View + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" + android:visibility="invisible" /> + + <com.google.android.setupdesign.view.IntrinsicSizeFrameLayout + style="@style/SudGlifCardContainer" + android:layout_width="@dimen/sud_glif_card_width" + android:layout_height="wrap_content" + android:height="@dimen/sud_glif_card_height"> + + <include layout="@layout/sud_glif_preference_template_content" /> + + </com.google.android.setupdesign.view.IntrinsicSizeFrameLayout> + + <View + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" + android:visibility="invisible" /> + +</LinearLayout> diff --git a/main/res/layout/sud_glif_header.xml b/main/res/layout/sud_glif_header.xml index 50feeb2..1bbde55 100644 --- a/main/res/layout/sud_glif_header.xml +++ b/main/res/layout/sud_glif_header.xml @@ -73,8 +73,6 @@ android:layout_height="wrap_content" android:layout_marginLeft="?attr/sudMarginStart" android:layout_marginRight="?attr/sudMarginStart" - android:layout_marginBottom="@dimen/sud_progress_bar_margin_vertical" - android:layout_marginTop="@dimen/sud_progress_bar_margin_vertical" android:visibility="gone" android:indeterminate="true" /> diff --git a/main/res/values-h720dp/dimens.xml b/main/res/values-h720dp/dimens.xml new file mode 100644 index 0000000..e495f71 --- /dev/null +++ b/main/res/values-h720dp/dimens.xml @@ -0,0 +1,26 @@ +<?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 xmlns:tools="http://schemas.android.com/tools"> + + <!-- Device default style --> + + <!-- Copy from Widget.DeviceDefault.Button.ButtonBar.AlertDialog --> + <!-- Dialog button bar height --> + <dimen name="sud_alert_dialog_button_bar_height">54dip</dimen> + +</resources> diff --git a/main/res/values-sw600dp-v31/layouts.xml b/main/res/values-sw600dp-v31/layouts.xml new file mode 100644 index 0000000..b013475 --- /dev/null +++ b/main/res/values-sw600dp-v31/layouts.xml @@ -0,0 +1,22 @@ +<?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 xmlns:tools="http://schemas.android.com/tools"> + + <item name="sud_glif_preference_template" type="layout">@layout/sud_glif_preference_template_card</item> + +</resources> diff --git a/main/res/values-v31/colors.xml b/main/res/values-v31/colors.xml index 91587ee..3db968b 100644 --- a/main/res/values-v31/colors.xml +++ b/main/res/values-v31/colors.xml @@ -38,6 +38,8 @@ <color name="sud_system_accent1_200">@android:color/system_accent1_200</color> + <color name="sud_system_accent1_300">@android:color/system_accent1_300</color> + <color name="sud_system_accent1_600">@android:color/system_accent1_600</color> @@ -46,19 +48,23 @@ <color name="sud_system_neutral1_50">@android:color/system_neutral1_50</color> + <color name="sud_system_neutral1_400">@android:color/system_neutral1_400</color> + + <color name="sud_system_neutral1_700">@android:color/system_neutral1_700</color> + <color name="sud_system_neutral1_800">@android:color/system_neutral1_800</color> <color name="sud_system_neutral1_900">@android:color/system_neutral1_900</color> - <color name="sud_system_neutral2_50">@android:color/system_neutral1_50</color> + <color name="sud_system_neutral2_50">@android:color/system_neutral2_50</color> - <color name="sud_system_neutral2_100">@android:color/system_neutral1_100</color> + <color name="sud_system_neutral2_100">@android:color/system_neutral2_100</color> <color name="sud_system_neutral2_200">@android:color/system_neutral2_200</color> - <color name="sud_system_neutral2_300">@android:color/system_accent2_300</color> + <color name="sud_system_neutral2_300">@android:color/system_neutral2_300</color> <color name="sud_system_neutral2_400">@android:color/system_neutral2_400</color> @@ -77,4 +83,17 @@ <color name="sud_system_button_text">@color/sud_system_neutral1_900</color> <color name="sud_system_dividing_line">@color/sud_system_neutral2_300</color> -</resources>
\ No newline at end of file + + <color name="sud_dynamic_switch_thumb_off_light">@color/sud_system_neutral2_300</color> + + <color name="sud_dynamic_switch_track_off_dark">@color/sud_system_neutral1_700</color> + + <color name="sud_dynamic_switch_thumb_off_dark">@color/sud_system_neutral1_400</color> + + + <color name="sud_dynamic_switch_track_on_light">@color/sud_system_accent1_600</color> + + <color name="sud_dynamic_switch_thumb_on_light">@color/sud_system_accent1_100</color> + + <color name="sud_dynamic_switch_thumb_on_dark">@color/sud_system_accent1_100</color> +</resources> diff --git a/main/res/values-v31/styles.xml b/main/res/values-v31/styles.xml index e1240e4..4fa3012 100644 --- a/main/res/values-v31/styles.xml +++ b/main/res/values-v31/styles.xml @@ -15,24 +15,32 @@ limitations under the License. --> -<resources> +<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Main theme for dynamic color --> <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="android:textColorLink">@color/sud_system_accent1_300</item> <item name="alertDialogTheme">@style/SudDynamicColorAlertDialogThemeCompat</item> <item name="android:datePickerDialogTheme">@style/SudDynamicColorDateTimePickerDialogTheme</item> <item name="android:timePickerDialogTheme">@style/SudDynamicColorDateTimePickerDialogTheme</item> <item name="sucFullDynamicColor">false</item> + <item name="sudSwitchBarThumbOnColor">@color/sud_dynamic_switch_thumb_on_dark</item> + <item name="sudSwitchBarTrackOnColor">@color/sud_dynamic_switch_track_on_dark</item> + <item name="sudSwitchBarThumbOffColor">@color/sud_dynamic_switch_thumb_off_dark</item> + <item name="sudSwitchBarTrackOffColor">@color/sud_dynamic_switch_track_off_dark</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="android:textColorLink">@color/sud_system_accent1_600</item> <item name="alertDialogTheme">@style/SudDynamicColorAlertDialogThemeCompat.Light</item> <item name="android:datePickerDialogTheme">@style/SudDynamicColorDateTimePickerDialogTheme.Light</item> <item name="android:timePickerDialogTheme">@style/SudDynamicColorDateTimePickerDialogTheme.Light</item> <item name="sucFullDynamicColor">false</item> + <item name="sudSwitchBarThumbOnColor">@color/sud_dynamic_switch_thumb_on_light</item> + <item name="sudSwitchBarTrackOnColor">@color/sud_dynamic_switch_track_on_light</item> + <item name="sudSwitchBarThumbOffColor">@color/sud_dynamic_switch_thumb_off_light</item> + <item name="sudSwitchBarTrackOffColor">@color/sud_dynamic_switch_track_off_light</item> </style> <style name="SudFullDynamicColorThemeGlifV3" parent="SudDynamicColorThemeGlifV3"> @@ -90,6 +98,8 @@ <item name="android:colorBackground">@color/sud_glif_v3_dialog_background_color_dark</item> <item name="colorAccent">@color/sud_dynamic_color_accent_glif_v3_dark</item> <item name="dialogCornerRadius">@dimen/sud_glif_device_default_dialog_corner_radius</item> + <item name="buttonBarButtonStyle">@style/SudAppCompatButtonButtonBarAlertDialog</item> + <item name="android:windowTitleStyle">@style/SudWindowTitleStyle</item> </style> <style name="SudDynamicColorAlertDialogThemeCompat.Light" parent="Theme.AppCompat.Light.Dialog.Alert"> @@ -97,6 +107,27 @@ <item name="android:colorBackground">@color/sud_glif_v3_dialog_background_color_light</item> <item name="colorAccent">@color/sud_dynamic_color_accent_glif_v3_light</item> <item name="dialogCornerRadius">@dimen/sud_glif_device_default_dialog_corner_radius</item> + <item name="buttonBarButtonStyle">@style/SudAppCompatButtonButtonBarAlertDialog.Light</item> + <item name="android:windowTitleStyle">@style/SudWindowTitleStyle</item> + </style> + + <style name="SudAppCompatButtonButtonBarAlertDialog" parent="Widget.AppCompat.ButtonBar.AlertDialog"> + <item name="android:textAppearance">@style/SudTextAppearanceDeviceDefaultMedium</item> + <item name="android:minWidth">@dimen/sud_alert_dialog_button_bar_width</item> + <item name="android:minHeight">@dimen/sud_alert_dialog_button_bar_height</item> + </style> + + <style name="SudAppCompatButtonButtonBarAlertDialog.Light" parent="SudAppCompatButtonButtonBarAlertDialog"> + <item name="android:textAppearance">@style/SudTextAppearanceDeviceDefaultMedium.Light</item> + </style> + + <style name="SudWindowTitleStyle" parent="RtlOverlay.DialogWindowTitle.AppCompat"> + <item name="android:textAppearance">@style/SudDeviceDefaultWindowTitleTextAppearance</item> + </style> + + <style name="SudDeviceDefaultWindowTitleTextAppearance" parent="android:TextAppearance.DeviceDefault.WindowTitle"> + <item name="android:textSize">@dimen/sud_alert_dialog_title_text_size</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> </style> <style name="SudFullDynamicColorAlertDialogThemeCompat" parent="SudDynamicColorAlertDialogThemeCompat"> @@ -117,4 +148,100 @@ <item name="dialogCornerRadius">@dimen/sud_glif_device_default_dialog_corner_radius</item> </style> + <style name="SudAlertDialogTheme" parent="android:Theme.DeviceDefault.Dialog.Alert"> + <item name="android:colorBackground">@color/sud_glif_v3_dialog_background_color_dark</item> + <item name="android:buttonBarButtonStyle">@style/SudDeviceDefaultButtonBarButtonStyle</item> + </style> + + <style name="SudAlertDialogTheme.Light" parent="android:Theme.DeviceDefault.Light.Dialog.Alert"> + <item name="android:buttonBarButtonStyle">@style/SudDeviceDefaultButtonBarButtonStyle.Light</item> + </style> + + <!-- Can't set style Widget.DeviceDefault.Button.ButtonBar.AlertDialog as parent theme directly, + since it is not public. Thus here sets Widget.DeviceDefault.Button.Borderless.Colored and + bring the minWidth/minHeight. --> + <style name="SudDeviceDefaultButtonBarButtonStyle" parent="android:Widget.DeviceDefault.Button.Borderless.Colored"> + <item name="android:textAppearance">@style/SudTextAppearanceDeviceDefaultMedium</item> + <item name="android:minWidth">@dimen/sud_alert_dialog_button_bar_width</item> + <item name="android:minHeight">@dimen/sud_alert_dialog_button_bar_height</item> + </style> + + <style name="SudDeviceDefaultButtonBarButtonStyle.Light" parent="SudDeviceDefaultButtonBarButtonStyle"> + <item name="android:textAppearance">@style/SudTextAppearanceDeviceDefaultMedium.Light</item> + </style> + + <style name="SudTextAppearanceDeviceDefaultMedium" parent="android:TextAppearance.DeviceDefault.Medium"> + <item name="android:textSize">@dimen/sud_alert_dialog_button_bar_button_text_size</item> + <item name="android:textColor">@color/sud_dynamic_color_accent_glif_v3_dark</item> + <item name="android:textAllCaps">false</item> + </style> + + <style name="SudTextAppearanceDeviceDefaultMedium.Light" parent="SudTextAppearanceDeviceDefaultMedium"> + <item name="android:textColor">@color/sud_dynamic_color_accent_glif_v3_light</item> + </style> + + <style name="SudThemeGlif" parent="SudBaseThemeGlif"> + <item name="sucSystemNavBarBackgroundColor">?android:attr/navigationBarColor</item> + <item name="android:windowSplashScreenBackground">?android:attr/colorBackground</item> + </style> + + <style name="SudThemeGlif.Light" parent="SudBaseThemeGlif.Light"> + <item name="sucSystemNavBarBackgroundColor">?android:attr/navigationBarColor</item> + <item name="android:windowSplashScreenBackground">?android:attr/colorBackground</item> + </style> + + <style name="SudThemeGlifV3" parent="SudBaseThemeGlifV3"> + + <!-- Copied from v27 SudThemeGlifV3 --> + <item name="android:navigationBarColor">@color/sud_glif_v3_nav_bar_color_dark</item> + <item name="android:navigationBarDividerColor" tools:ignore="NewApi">@color/sud_glif_v3_nav_bar_divider_color_dark</item> + <item name="android:windowLightNavigationBar" tools:ignore="NewApi">false</item> + <item name="sucLightSystemNavBar" tools:ignore="NewApi">?android:attr/windowLightNavigationBar</item> + <item name="sucSystemNavBarDividerColor" tools:ignore="NewApi">?android:attr/navigationBarDividerColor</item> + + <!-- Default font family--> + <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault</item> + <item name="android:textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Inverse</item> + <item name="android:textAppearanceLarge">@android:style/TextAppearance.DeviceDefault.Large</item> + <item name="android:textAppearanceMedium">@android:style/TextAppearance.DeviceDefault.Medium</item> + <!-- For textView --> + <item name="android:textAppearanceSmall">@android:style/TextAppearance.DeviceDefault.Small</item> + <item name="android:textAppearanceLargeInverse">@android:style/TextAppearance.DeviceDefault.Large.Inverse</item> + <!-- For editText --> + <item name="android:textAppearanceMediumInverse">@android:style/TextAppearance.DeviceDefault.Medium.Inverse</item> + <item name="android:textAppearanceSmallInverse">@android:style/TextAppearance.DeviceDefault.Small.Inverse</item> + <item name="android:textAppearanceSearchResultTitle">@android:style/TextAppearance.DeviceDefault.SearchResult.Title</item> + <item name="android:textAppearanceSearchResultSubtitle">@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle</item> + <item name="android:textAppearanceButton">@android:style/TextAppearance.DeviceDefault.Widget.Button</item> + <item name="android:textAppearanceLargePopupMenu">@android:style/TextAppearance.DeviceDefault.Widget.PopupMenu.Large</item> + <item name="android:textAppearanceSmallPopupMenu">@android:style/TextAppearance.DeviceDefault.Widget.PopupMenu.Small</item> + </style> + + <style name="SudThemeGlifV3.Light" parent="SudBaseThemeGlifV3.Light"> + + <!-- Copied from v27 SudThemeGlifV3.Light --> + <item name="android:navigationBarColor">@color/sud_glif_v3_nav_bar_color_light</item> + <item name="android:navigationBarDividerColor">@color/sud_glif_v3_nav_bar_divider_color_light</item> + <item name="android:windowLightNavigationBar">true</item> + <item name="sucLightSystemNavBar" tools:ignore="NewApi">?android:attr/windowLightNavigationBar</item> + <item name="sucSystemNavBarDividerColor" tools:ignore="NewApi">?android:attr/navigationBarDividerColor</item> + + <!-- Default font family--> + <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault</item> + <item name="android:textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Inverse</item> + <item name="android:textAppearanceLarge">@android:style/TextAppearance.DeviceDefault.Large</item> + <item name="android:textAppearanceMedium">@android:style/TextAppearance.DeviceDefault.Medium</item> + <!-- For textView --> + <item name="android:textAppearanceSmall">@android:style/TextAppearance.DeviceDefault.Small</item> + <item name="android:textAppearanceLargeInverse">@android:style/TextAppearance.DeviceDefault.Large.Inverse</item> + <!-- For editText --> + <item name="android:textAppearanceMediumInverse">@android:style/TextAppearance.DeviceDefault.Medium.Inverse</item> + <item name="android:textAppearanceSmallInverse">@android:style/TextAppearance.DeviceDefault.Small.Inverse</item> + <item name="android:textAppearanceSearchResultTitle">@android:style/TextAppearance.DeviceDefault.SearchResult.Title</item> + <item name="android:textAppearanceSearchResultSubtitle">@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle</item> + <item name="android:textAppearanceButton">@android:style/TextAppearance.DeviceDefault.Widget.Button</item> + <item name="android:textAppearanceLargePopupMenu">@android:style/TextAppearance.DeviceDefault.Widget.PopupMenu.Large</item> + <item name="android:textAppearanceSmallPopupMenu">@android:style/TextAppearance.DeviceDefault.Widget.PopupMenu.Small</item> + </style> + </resources> diff --git a/main/res/values/attrs.xml b/main/res/values/attrs.xml index c946912..3f167ac 100644 --- a/main/res/values/attrs.xml +++ b/main/res/values/attrs.xml @@ -187,6 +187,7 @@ <attr name="android:summary" /> <attr name="android:title" /> <attr name="android:visible" /> + <attr name="android:contentDescription" /> <attr name="sudIconTint" /> <attr name="sudIconGravity" /> </declare-styleable> @@ -259,4 +260,10 @@ </declare-styleable> <attr name="sudLoadingHeaderHeight" format="dimension|reference" /> + + <!-- Glif Switch Bar style --> + <attr name="sudSwitchBarThumbOnColor" format="color|reference" /> + <attr name="sudSwitchBarThumbOffColor" format="color|reference" /> + <attr name="sudSwitchBarTrackOnColor" format="color|reference" /> + <attr name="sudSwitchBarTrackOffColor" format="color|reference" /> </resources> diff --git a/main/res/values/colors.xml b/main/res/values/colors.xml index 798abc9..3fe0b4b 100644 --- a/main/res/values/colors.xml +++ b/main/res/values/colors.xml @@ -140,8 +140,19 @@ <color name="sud_portal_pending_progress">@color/sud_portal_pending_progress_light</color> - <color name="sud_switch_track_off">#FF757575</color> - <color name="sud_switch_thumb_off">#BFFFFFFF</color> + + <color name="sud_switch_track_off_light">#FF55575E</color> + <color name="sud_switch_thumb_off_light">#FFA5ACB2</color> + <color name="sud_switch_track_off_dark">#FF454749</color> + <color name="sud_switch_thumb_off_dark">#FF8F9193</color> + + <color name="sud_switch_track_on_light">#3B78E7</color> + + <color name="sud_switch_thumb_on_light">#C6DAFC</color> + + <color name="sud_switch_track_on_dark">#824285F4</color> + + <color name="sud_switch_thumb_on_dark">#C6DAFC</color> <color name="sud_uniformity_backdrop_color">@android:color/white</color> diff --git a/main/res/values/dimens.xml b/main/res/values/dimens.xml index 64970c8..a5aaca6 100644 --- a/main/res/values/dimens.xml +++ b/main/res/values/dimens.xml @@ -17,6 +17,19 @@ <resources xmlns:tools="http://schemas.android.com/tools"> + <!-- Device default style --> + + <!-- Copy from Widget.DeviceDefault.Button.ButtonBar.AlertDialog --> + <!-- Dialog button bar width --> + <dimen name="sud_alert_dialog_button_bar_width">64dp</dimen> + <!-- Dialog button bar height --> + <dimen name="sud_alert_dialog_button_bar_height">48dip</dimen> + + <!-- Dialog button bar button text size --> + <dimen name="sud_alert_dialog_button_bar_button_text_size">14sp</dimen> + <!-- Dialog title text size --> + <dimen name="sud_alert_dialog_title_text_size">20sp</dimen> + <!-- General --> <dimen name="sud_layout_margin_sides">40dp</dimen> @@ -37,6 +50,7 @@ <dimen name="sud_glif_margin_start">24dp</dimen> <dimen name="sud_glif_margin_end">24dp</dimen> <dimen name="sud_glif_icon_margin_top">56dp</dimen> + <dimen name="sud_horizontal_icon_height">32dp</dimen> <dimen name="sud_glif_alert_dialog_corner_radius">8dp</dimen> <dimen name="sud_glif_v3_button_corner_radius">4dp</dimen> @@ -181,6 +195,8 @@ <!-- Progress bar --> <!-- The margin to compensate for the padding built-in to the widget itself --> <dimen name="sud_progress_bar_margin_vertical">-7dp</dimen> + <dimen name="sud_progress_bar_margin_top">-7dp</dimen> + <dimen name="sud_progress_bar_margin_bottom">-7dp</dimen> <dimen name="sud_glif_progress_bar_margin_vertical">7dp</dimen> <dimen name="sud_glif_progress_bar_padding">40dp</dimen> diff --git a/main/res/values/styles.xml b/main/res/values/styles.xml index 4725735..c6dea59 100644 --- a/main/res/values/styles.xml +++ b/main/res/values/styles.xml @@ -187,6 +187,10 @@ <item name="sudContentIllustrationPaddingTop">@dimen/sud_content_illustration_padding_vertical</item> <item name="sudContentIllustrationPaddingBottom">@dimen/sud_content_illustration_padding_vertical</item> <item name="sudLoadingHeaderHeight">@dimen/sud_loading_header_height</item> + <item name="sudSwitchBarThumbOnColor">@color/sud_switch_thumb_on_dark</item> + <item name="sudSwitchBarTrackOnColor">@color/sud_switch_track_on_dark</item> + <item name="sudSwitchBarThumbOffColor">@color/sud_switch_thumb_off_dark</item> + <item name="sudSwitchBarTrackOffColor">@color/sud_switch_track_off_dark</item> </style> <style name="SudThemeGlif" parent="SudBaseThemeGlif"/> @@ -264,6 +268,10 @@ <item name="sudContentIllustrationPaddingTop">@dimen/sud_content_illustration_padding_vertical</item> <item name="sudContentIllustrationPaddingBottom">@dimen/sud_content_illustration_padding_vertical</item> <item name="sudLoadingHeaderHeight">@dimen/sud_loading_header_height</item> + <item name="sudSwitchBarThumbOnColor">@color/sud_switch_thumb_on_light</item> + <item name="sudSwitchBarTrackOnColor">@color/sud_switch_track_on_light</item> + <item name="sudSwitchBarThumbOffColor">@color/sud_switch_thumb_off_light</item> + <item name="sudSwitchBarTrackOffColor">@color/sud_switch_track_off_light</item> </style> <style name="SudThemeGlif.Light" parent="SudBaseThemeGlif.Light"/> @@ -693,6 +701,8 @@ <item name="android:fontFamily" tools:targetApi="jelly_bean">@string/sudFontSecondary</item> <item name="android:textAlignment" tools:targetApi="jelly_bean_mr1">gravity</item> <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textDirection" tools:targetApi="jelly_bean_mr1">locale</item> + <item name="android:accessibilityHeading" tools:targetApi="p">true</item> </style> <style name="SudGlifDescription" parent="SudDescription.Glif"> @@ -704,6 +714,7 @@ <item name="android:layout_marginEnd">?attr/sudMarginEnd</item> <item name="android:fontFamily" tools:targetApi="jelly_bean">@string/sudFontSecondary</item> <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textDirection" tools:targetApi="jelly_bean_mr1">locale</item> </style> <style name="SudGlifHeaderContainer"> diff --git a/main/src/com/google/android/setupdesign/DividerItemDecoration.java b/main/src/com/google/android/setupdesign/DividerItemDecoration.java index df86b23..dabe36f 100644 --- a/main/src/com/google/android/setupdesign/DividerItemDecoration.java +++ b/main/src/com/google/android/setupdesign/DividerItemDecoration.java @@ -21,10 +21,10 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import androidx.core.view.ViewCompat; import androidx.recyclerview.widget.RecyclerView; import android.view.View; import androidx.annotation.IntDef; +import androidx.core.view.ViewCompat; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/main/src/com/google/android/setupdesign/GlifLayout.java b/main/src/com/google/android/setupdesign/GlifLayout.java index 829e3d7..1b8c8f8 100644 --- a/main/src/com/google/android/setupdesign/GlifLayout.java +++ b/main/src/com/google/android/setupdesign/GlifLayout.java @@ -50,7 +50,6 @@ import com.google.android.setupdesign.template.RequireScrollMixin; import com.google.android.setupdesign.template.ScrollViewScrollHandlingDelegate; import com.google.android.setupdesign.util.DescriptionStyler; import com.google.android.setupdesign.util.LayoutStyler; -import com.google.android.setupdesign.util.PartnerStyleHelper; /** * Layout for the GLIF theme used in Setup Wizard for N. @@ -137,12 +136,13 @@ public class GlifLayout extends PartnerCustomizationLayout { if (primaryColor != null) { setPrimaryColor(primaryColor); } - - if (applyPartnerHeavyThemeResource) { + if (shouldApplyPartnerHeavyThemeResource()) { updateContentBackgroundColorWithPartnerConfig(); + } - View view = findManagedViewById(R.id.sud_layout_content); - if (view != null) { + View view = findManagedViewById(R.id.sud_layout_content); + if (view != null) { + if (shouldApplyPartnerResource()) { // The margin of content is defined by @style/SudContentFrame. The Setupdesign library // cannot obtain the content resource ID of the client, so the value of the content margin // cannot be adjusted through GlifLayout. If the margin sides are changed through the @@ -150,10 +150,16 @@ public class GlifLayout extends PartnerCustomizationLayout { // value of pading. In this way, the value of content margin plus padding will be equal to // the value of partner config. LayoutStyler.applyPartnerCustomizationExtraPaddingStyle(view); + } - applyPartnerCustomizationContentPaddingTopStyle(view); + // {@class GlifPreferenceLayout} Inherited from {@class GlifRecyclerLayout}. The API would + // be called twice from GlifRecyclerLayout and GlifLayout, so it should skip the API here + // when the instance is GlifPreferenceLayout. + if (!(this instanceof GlifPreferenceLayout)) { + tryApplyPartnerCustomizationContentPaddingTopStyle(view); } } + updateLandscapeMiddleHorizontalSpacing(); ColorStateList backgroundColor = @@ -177,6 +183,7 @@ public class GlifLayout extends PartnerCustomizationLayout { getMixin(IconMixin.class).tryApplyPartnerCustomizationStyle(); getMixin(HeaderMixin.class).tryApplyPartnerCustomizationStyle(); getMixin(DescriptionMixin.class).tryApplyPartnerCustomizationStyle(); + getMixin(ProgressBarMixin.class).tryApplyPartnerCustomizationStyle(); tryApplyPartnerCustomizationStyleToShortDescription(); } @@ -196,59 +203,77 @@ public class GlifLayout extends PartnerCustomizationLayout { protected void updateLandscapeMiddleHorizontalSpacing() { int horizontalSpacing = getResources().getDimensionPixelSize(R.dimen.sud_glif_land_middle_horizontal_spacing); + if (shouldApplyPartnerResource() + && PartnerConfigHelper.get(getContext()) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAND_MIDDLE_HORIZONTAL_SPACING)) { + horizontalSpacing = + (int) + PartnerConfigHelper.get(getContext()) + .getDimension(getContext(), PartnerConfig.CONFIG_LAND_MIDDLE_HORIZONTAL_SPACING); + } View headerView = this.findManagedViewById(R.id.sud_landscape_header_area); if (headerView != null) { - if (PartnerConfigHelper.get(getContext()) - .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_END)) { - int layoutMarginEnd = + int layoutMarginEnd; + if (shouldApplyPartnerResource() + && PartnerConfigHelper.get(getContext()) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_END)) { + layoutMarginEnd = (int) PartnerConfigHelper.get(getContext()) .getDimension(getContext(), PartnerConfig.CONFIG_LAYOUT_MARGIN_END); - - int paddingEnd = (horizontalSpacing / 2) - layoutMarginEnd; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - headerView.setPadding( - headerView.getPaddingStart(), - headerView.getPaddingTop(), - paddingEnd, - headerView.getPaddingBottom()); - } else { - headerView.setPadding( - headerView.getPaddingLeft(), - headerView.getPaddingTop(), - paddingEnd, - headerView.getPaddingBottom()); - } + } else { + TypedArray a = getContext().obtainStyledAttributes(new int[] {R.attr.sudMarginEnd}); + layoutMarginEnd = a.getDimensionPixelSize(0, 0); + a.recycle(); + } + int paddingEnd = (horizontalSpacing / 2) - layoutMarginEnd; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + headerView.setPadding( + headerView.getPaddingStart(), + headerView.getPaddingTop(), + paddingEnd, + headerView.getPaddingBottom()); + } else { + headerView.setPadding( + headerView.getPaddingLeft(), + headerView.getPaddingTop(), + paddingEnd, + headerView.getPaddingBottom()); } } View contentView = this.findManagedViewById(R.id.sud_landscape_content_area); if (contentView != null) { - if (PartnerConfigHelper.get(getContext()) - .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_START)) { - int layoutMarginStart = + int layoutMarginStart; + if (shouldApplyPartnerResource() + && PartnerConfigHelper.get(getContext()) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_START)) { + layoutMarginStart = (int) PartnerConfigHelper.get(getContext()) .getDimension(getContext(), PartnerConfig.CONFIG_LAYOUT_MARGIN_START); - - int paddingStart = 0; - if (headerView != null) { - paddingStart = (horizontalSpacing / 2) - layoutMarginStart; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - contentView.setPadding( - paddingStart, - contentView.getPaddingTop(), - contentView.getPaddingEnd(), - contentView.getPaddingBottom()); - } else { - contentView.setPadding( - paddingStart, - contentView.getPaddingTop(), - contentView.getPaddingRight(), - contentView.getPaddingBottom()); - } + } else { + TypedArray a = getContext().obtainStyledAttributes(new int[] {R.attr.sudMarginStart}); + layoutMarginStart = a.getDimensionPixelSize(0, 0); + a.recycle(); + } + int paddingStart = 0; + if (headerView != null) { + paddingStart = (horizontalSpacing / 2) - layoutMarginStart; + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + contentView.setPadding( + paddingStart, + contentView.getPaddingTop(), + contentView.getPaddingEnd(), + contentView.getPaddingBottom()); + } else { + contentView.setPadding( + paddingStart, + contentView.getPaddingTop(), + contentView.getPaddingRight(), + contentView.getPaddingBottom()); } } } @@ -472,14 +497,13 @@ public class GlifLayout extends PartnerCustomizationLayout { } @TargetApi(VERSION_CODES.JELLY_BEAN_MR1) - protected static void applyPartnerCustomizationContentPaddingTopStyle(View view) { + protected void tryApplyPartnerCustomizationContentPaddingTopStyle(View view) { Context context = view.getContext(); boolean partnerPaddingTopAvailable = PartnerConfigHelper.get(context) .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_PADDING_TOP); - if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(view) - && partnerPaddingTopAvailable) { + if (shouldApplyPartnerResource() && partnerPaddingTopAvailable) { int paddingTop = (int) PartnerConfigHelper.get(context) diff --git a/main/src/com/google/android/setupdesign/GlifListLayout.java b/main/src/com/google/android/setupdesign/GlifListLayout.java index 60f0343..89d0888 100644 --- a/main/src/com/google/android/setupdesign/GlifListLayout.java +++ b/main/src/com/google/android/setupdesign/GlifListLayout.java @@ -76,7 +76,7 @@ public class GlifListLayout extends GlifLayout { View view = this.findManagedViewById(R.id.sud_landscape_content_area); if (view != null) { - applyPartnerCustomizationContentPaddingTopStyle(view); + tryApplyPartnerCustomizationContentPaddingTopStyle(view); } updateLandscapeMiddleHorizontalSpacing(); } diff --git a/main/src/com/google/android/setupdesign/GlifRecyclerLayout.java b/main/src/com/google/android/setupdesign/GlifRecyclerLayout.java index 5e75436..87f871c 100644 --- a/main/src/com/google/android/setupdesign/GlifRecyclerLayout.java +++ b/main/src/com/google/android/setupdesign/GlifRecyclerLayout.java @@ -77,7 +77,7 @@ public class GlifRecyclerLayout extends GlifLayout { View view = this.findManagedViewById(R.id.sud_landscape_content_area); if (view != null) { - applyPartnerCustomizationContentPaddingTopStyle(view); + tryApplyPartnerCustomizationContentPaddingTopStyle(view); } updateLandscapeMiddleHorizontalSpacing(); } diff --git a/main/src/com/google/android/setupdesign/accessibility/LinkAccessibilityHelper.java b/main/src/com/google/android/setupdesign/accessibility/LinkAccessibilityHelper.java index 1a55b25..237cd83 100644 --- a/main/src/com/google/android/setupdesign/accessibility/LinkAccessibilityHelper.java +++ b/main/src/com/google/android/setupdesign/accessibility/LinkAccessibilityHelper.java @@ -19,9 +19,6 @@ package com.google.android.setupdesign.accessibility; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; -import androidx.core.view.AccessibilityDelegateCompat; -import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; -import androidx.core.view.accessibility.AccessibilityNodeProviderCompat; import android.text.Layout; import android.text.Spanned; import android.text.style.ClickableSpan; @@ -33,6 +30,9 @@ import android.view.accessibility.AccessibilityEvent; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import androidx.core.view.AccessibilityDelegateCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; +import androidx.core.view.accessibility.AccessibilityNodeProviderCompat; import androidx.customview.widget.ExploreByTouchHelper; import java.util.List; diff --git a/main/src/com/google/android/setupdesign/items/ExpandableSwitchItem.java b/main/src/com/google/android/setupdesign/items/ExpandableSwitchItem.java index 29eaf23..c934612 100644 --- a/main/src/com/google/android/setupdesign/items/ExpandableSwitchItem.java +++ b/main/src/com/google/android/setupdesign/items/ExpandableSwitchItem.java @@ -24,16 +24,16 @@ import android.graphics.drawable.Drawable; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.os.Bundle; -import androidx.core.view.AccessibilityDelegateCompat; -import androidx.core.view.ViewCompat; -import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; -import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.TextView; +import androidx.core.view.AccessibilityDelegateCompat; +import androidx.core.view.ViewCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; import com.google.android.setupdesign.R; import com.google.android.setupdesign.util.LayoutStyler; import com.google.android.setupdesign.view.CheckableLinearLayout; diff --git a/main/src/com/google/android/setupdesign/items/Item.java b/main/src/com/google/android/setupdesign/items/Item.java index fd3f2eb..ff2e3ce 100644 --- a/main/src/com/google/android/setupdesign/items/Item.java +++ b/main/src/com/google/android/setupdesign/items/Item.java @@ -44,6 +44,7 @@ public class Item extends AbstractItem { private int layoutRes; @Nullable private CharSequence summary; @Nullable private CharSequence title; + @Nullable private CharSequence contentDescription; private boolean visible = true; @ColorInt private int iconTint = Color.TRANSPARENT; private int iconGravity = Gravity.CENTER_VERTICAL; @@ -60,6 +61,7 @@ public class Item extends AbstractItem { icon = a.getDrawable(R.styleable.SudItem_android_icon); title = a.getText(R.styleable.SudItem_android_title); summary = a.getText(R.styleable.SudItem_android_summary); + contentDescription = a.getText(R.styleable.SudItem_android_contentDescription); layoutRes = a.getResourceId(R.styleable.SudItem_android_layout, getDefaultLayoutResource()); visible = a.getBoolean(R.styleable.SudItem_android_visible, true); iconTint = a.getColor(R.styleable.SudItem_sudIconTint, Color.TRANSPARENT); @@ -143,6 +145,16 @@ public class Item extends AbstractItem { return title; } + @Nullable + public CharSequence getContentDescription() { + return contentDescription; + } + + public void setContentDescription(@Nullable CharSequence contentDescription) { + this.contentDescription = contentDescription; + notifyItemChanged(); + } + public void setVisible(boolean visible) { if (this.visible == visible) { return; @@ -178,6 +190,8 @@ public class Item extends AbstractItem { summaryView.setVisibility(View.GONE); } + view.setContentDescription(getContentDescription()); + final View iconContainer = view.findViewById(R.id.sud_items_icon_container); final Drawable icon = getIcon(); if (icon != null) { @@ -208,6 +222,7 @@ public class Item extends AbstractItem { // get its child view to adjust it first, so skip the Layout padding adjustment. // If the item view is a header layout, it doesn't need to adjust the layout padding start/end // here. It will be adjusted by HeaderMixin. + // TODO: Add partner resource enable check if (!(this instanceof ExpandableSwitchItem) && view.getId() != R.id.sud_layout_header) { LayoutStyler.applyPartnerCustomizationLayoutPaddingStyle(view); } diff --git a/main/src/com/google/android/setupdesign/template/DescriptionMixin.java b/main/src/com/google/android/setupdesign/template/DescriptionMixin.java index bbccf82..63e4f41 100644 --- a/main/src/com/google/android/setupdesign/template/DescriptionMixin.java +++ b/main/src/com/google/android/setupdesign/template/DescriptionMixin.java @@ -28,7 +28,6 @@ import androidx.annotation.AttrRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; -import com.google.android.setupcompat.PartnerCustomizationLayout; import com.google.android.setupcompat.internal.TemplateLayout; import com.google.android.setupcompat.template.Mixin; import com.google.android.setupdesign.R; @@ -79,21 +78,12 @@ public class DescriptionMixin implements Mixin { /** * Applies the partner customizations to the description text (contains text alignment) and - * background, if apply heavy theme resource, it will apply all partner customizations, otherwise, - * only apply alignment style. + * background. It will apply all partner customizations. */ public void tryApplyPartnerCustomizationStyle() { TextView description = templateLayout.findManagedViewById(R.id.sud_layout_subtitle); - boolean partnerHeavyThemeLayout = PartnerStyleHelper.isPartnerHeavyThemeLayout(templateLayout); - if (partnerHeavyThemeLayout) { - if (description != null) { - HeaderAreaStyler.applyPartnerCustomizationDescriptionHeavyStyle(description); - } - } else if (templateLayout instanceof PartnerCustomizationLayout - && ((PartnerCustomizationLayout) templateLayout).shouldApplyPartnerResource()) { - if (description != null) { - HeaderAreaStyler.applyPartnerCustomizationDescriptionLightStyle(description); - } + if (description != null && PartnerStyleHelper.shouldApplyPartnerResource(templateLayout)) { + HeaderAreaStyler.applyPartnerCustomizationDescriptionHeavyStyle(description); } } diff --git a/main/src/com/google/android/setupdesign/template/HeaderMixin.java b/main/src/com/google/android/setupdesign/template/HeaderMixin.java index d040c94..96f9f67 100644 --- a/main/src/com/google/android/setupdesign/template/HeaderMixin.java +++ b/main/src/com/google/android/setupdesign/template/HeaderMixin.java @@ -77,8 +77,8 @@ public class HeaderMixin implements Mixin { a.recycle(); - // overlay the Auto size config settings - updateAutoTextSizeWithPartnerConfig(); + // Try to update the flag of the uto size config settings + tryUpdateAutoTextSizeFlagWithPartnerConfig(); // Set the header text if (headerText != null) { @@ -90,10 +90,9 @@ public class HeaderMixin implements Mixin { } } - private void updateAutoTextSizeWithPartnerConfig() { + private void tryUpdateAutoTextSizeFlagWithPartnerConfig() { Context context = templateLayout.getContext(); - if (!PartnerStyleHelper.isPartnerHeavyThemeLayout(templateLayout) - || !PartnerConfigHelper.shouldApplyExtendedPartnerConfig(context)) { + if (!PartnerStyleHelper.shouldApplyPartnerResource(templateLayout)) { autoTextSizeEnabled = false; return; } @@ -149,18 +148,14 @@ public class HeaderMixin implements Mixin { */ public void tryApplyPartnerCustomizationStyle() { TextView header = templateLayout.findManagedViewById(R.id.suc_layout_title); - boolean partnerLightThemeLayout = PartnerStyleHelper.isPartnerLightThemeLayout(templateLayout); - boolean partnerHeavyThemeLayout = PartnerStyleHelper.isPartnerHeavyThemeLayout(templateLayout); - if (partnerHeavyThemeLayout) { + if (PartnerStyleHelper.shouldApplyPartnerResource(templateLayout)) { View headerAreaView = templateLayout.findManagedViewById(R.id.sud_layout_header); - HeaderAreaStyler.applyPartnerCustomizationHeaderHeavyStyle(header); - HeaderAreaStyler.applyPartnerCustomizationHeaderAreaStyle((ViewGroup) headerAreaView); LayoutStyler.applyPartnerCustomizationExtraPaddingStyle(headerAreaView); - // overlay the Auto size config settings - updateAutoTextSizeWithPartnerConfig(); - } else if (partnerLightThemeLayout) { - HeaderAreaStyler.applyPartnerCustomizationHeaderLightStyle(header); + HeaderAreaStyler.applyPartnerCustomizationHeaderStyle(header); + HeaderAreaStyler.applyPartnerCustomizationHeaderAreaStyle((ViewGroup) headerAreaView); } + // Try to update the flag of the uto size config settings + tryUpdateAutoTextSizeFlagWithPartnerConfig(); if (autoTextSizeEnabled) { // Override the text size setting of the header autoAdjustTextSize(header); diff --git a/main/src/com/google/android/setupdesign/template/IconMixin.java b/main/src/com/google/android/setupdesign/template/IconMixin.java index 75e624a..3c2b6d0 100644 --- a/main/src/com/google/android/setupdesign/template/IconMixin.java +++ b/main/src/com/google/android/setupdesign/template/IconMixin.java @@ -71,8 +71,8 @@ public class IconMixin implements Mixin { context.obtainStyledAttributes( attrs, R.styleable.SudIconMixin, defStyleAttr, /* defStyleRes= */ 0); - final @DrawableRes int icon = - a.getResourceId(R.styleable.SudIconMixin_android_icon, /* defValue= */ 0); + @DrawableRes + final int icon = a.getResourceId(R.styleable.SudIconMixin_android_icon, /* defValue= */ 0); if (icon != 0) { setIcon(icon); } @@ -81,8 +81,8 @@ public class IconMixin implements Mixin { a.getBoolean(R.styleable.SudIconMixin_sudUpscaleIcon, /* defValue= */ false); setUpscaleIcon(upscaleIcon); - final @ColorInt int iconTint = - a.getColor(R.styleable.SudIconMixin_sudIconTint, Color.TRANSPARENT); + @ColorInt + final int iconTint = a.getColor(R.styleable.SudIconMixin_sudIconTint, Color.TRANSPARENT); if (iconTint != Color.TRANSPARENT) { setIconTint(iconTint); } @@ -92,12 +92,9 @@ public class IconMixin implements Mixin { /** Tries to apply the partner customization to the header icon. */ public void tryApplyPartnerCustomizationStyle() { - if (PartnerStyleHelper.isPartnerHeavyThemeLayout(templateLayout)) { - // apply partner heavy configs + // apply partner configs for icon + if (PartnerStyleHelper.shouldApplyPartnerResource(templateLayout)) { HeaderAreaStyler.applyPartnerCustomizationIconStyle(getView(), getContainerView()); - } else if (PartnerStyleHelper.isPartnerLightThemeLayout(templateLayout)) { - // apply partner light configs - HeaderAreaStyler.applyPartnerCustomizationIconStyle(getView()); } } @@ -117,6 +114,7 @@ public class IconMixin implements Mixin { iconView.setImageDrawable(icon); iconView.setVisibility(icon != null ? View.VISIBLE : View.GONE); setIconContainerVisibility(iconView.getVisibility()); + tryApplyPartnerCustomizationStyle(); } } diff --git a/main/src/com/google/android/setupdesign/template/ListMixin.java b/main/src/com/google/android/setupdesign/template/ListMixin.java index 5963a79..bfaf640 100644 --- a/main/src/com/google/android/setupdesign/template/ListMixin.java +++ b/main/src/com/google/android/setupdesign/template/ListMixin.java @@ -79,7 +79,7 @@ public class ListMixin implements Mixin { int dividerInsetEnd = a.getDimensionPixelSize(R.styleable.SudListMixin_sudDividerInsetEnd, 0); - if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(templateLayout)) { + if (PartnerStyleHelper.shouldApplyPartnerResource(templateLayout)) { if (PartnerConfigHelper.get(context) .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_START)) { dividerInsetStart = diff --git a/main/src/com/google/android/setupdesign/template/ProgressBarMixin.java b/main/src/com/google/android/setupdesign/template/ProgressBarMixin.java index da1b997..ac5ac69 100644 --- a/main/src/com/google/android/setupdesign/template/ProgressBarMixin.java +++ b/main/src/com/google/android/setupdesign/template/ProgressBarMixin.java @@ -16,12 +16,14 @@ package com.google.android.setupdesign.template; +import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.os.Build; import android.os.Build.VERSION_CODES; import android.util.AttributeSet; import android.view.View; +import android.view.ViewGroup; import android.view.ViewStub; import android.widget.ProgressBar; import androidx.annotation.AttrRes; @@ -30,6 +32,8 @@ import androidx.annotation.Nullable; import com.google.android.setupcompat.internal.TemplateLayout; import com.google.android.setupcompat.template.Mixin; import com.google.android.setupdesign.R; +import com.google.android.setupdesign.util.HeaderAreaStyler; +import com.google.android.setupdesign.util.PartnerStyleHelper; /** A {@link Mixin} for showing a progress bar. */ public class ProgressBarMixin implements Mixin { @@ -178,4 +182,34 @@ public class ProgressBarMixin implements Mixin { public ColorStateList getColor() { return color; } + + /** + * Tries to apply the partner customizations to the progress bar. Use the default values if + * partner config isn't enable. + */ + public void tryApplyPartnerCustomizationStyle() { + ProgressBar progressBar = peekProgressBar(); + if (!useBottomProgressBar || progressBar == null) { + return; + } + + boolean partnerHeavyThemeLayout = PartnerStyleHelper.isPartnerHeavyThemeLayout(templateLayout); + + if (partnerHeavyThemeLayout) { + HeaderAreaStyler.applyPartnerCustomizationProgressBarStyle(progressBar); + } else { + Context context = progressBar.getContext(); + final ViewGroup.LayoutParams lp = progressBar.getLayoutParams(); + + if (lp instanceof ViewGroup.MarginLayoutParams) { + int marginTop = + (int) context.getResources().getDimension(R.dimen.sud_progress_bar_margin_top); + int marginBottom = + (int) context.getResources().getDimension(R.dimen.sud_progress_bar_margin_bottom); + + final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) lp; + mlp.setMargins(mlp.leftMargin, marginTop, mlp.rightMargin, marginBottom); + } + } + } } diff --git a/main/src/com/google/android/setupdesign/template/RecyclerMixin.java b/main/src/com/google/android/setupdesign/template/RecyclerMixin.java index b327060..c4e8f56 100644 --- a/main/src/com/google/android/setupdesign/template/RecyclerMixin.java +++ b/main/src/com/google/android/setupdesign/template/RecyclerMixin.java @@ -154,7 +154,7 @@ public class RecyclerMixin implements Mixin { int dividerInsetEnd = a.getDimensionPixelSize(R.styleable.SudRecyclerMixin_sudDividerInsetEnd, 0); - if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(templateLayout)) { + if (PartnerStyleHelper.shouldApplyPartnerResource(templateLayout)) { if (PartnerConfigHelper.get(context) .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_START)) { dividerInsetStart = @@ -269,6 +269,11 @@ public class RecyclerMixin implements Mixin { return dividerInsetEnd; } + /** Remove the divider inset from this RecyclerView. */ + public void removeDividerInset() { + recyclerView.removeItemDecoration(dividerDecoration); + } + private void updateDivider() { boolean shouldUpdate = true; if (Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT) { diff --git a/main/src/com/google/android/setupdesign/util/ContentStyler.java b/main/src/com/google/android/setupdesign/util/ContentStyler.java index d390780..ef365e3 100644 --- a/main/src/com/google/android/setupdesign/util/ContentStyler.java +++ b/main/src/com/google/android/setupdesign/util/ContentStyler.java @@ -41,6 +41,7 @@ import java.util.Locale; */ public final class ContentStyler { public static void applyBodyPartnerCustomizationStyle(TextView contentText) { + // TODO: Remove the check of applying the heavy theme. if (!PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(contentText)) { return; } @@ -52,6 +53,7 @@ public final class ContentStyler { PartnerConfig.CONFIG_CONTENT_LINK_TEXT_COLOR, PartnerConfig.CONFIG_CONTENT_TEXT_SIZE, PartnerConfig.CONFIG_CONTENT_FONT_FAMILY, + PartnerConfig.CONFIG_DESCRIPTION_LINK_FONT_FAMILY, null, null, ContentStyler.getPartnerContentTextGravity(contentText.getContext()))); @@ -68,6 +70,7 @@ public final class ContentStyler { */ public static void applyInfoPartnerCustomizationStyle( @Nullable View infoContainer, @Nullable ImageView infoIcon, TextView infoText) { + // TODO: Remove the check of applying the heavy theme. if (!PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(infoText)) { return; } @@ -80,6 +83,9 @@ public final class ContentStyler { boolean fontFamilyConfigAvailable = PartnerConfigHelper.get(context) .isPartnerConfigAvailable(PartnerConfig.CONFIG_CONTENT_INFO_FONT_FAMILY); + boolean linkFontFamilyConfigAvailable = + PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_DESCRIPTION_LINK_FONT_FAMILY); TextViewPartnerStyler.applyPartnerCustomizationStyle( infoText, @@ -88,6 +94,9 @@ public final class ContentStyler { null, textSizeConfigAvailable ? PartnerConfig.CONFIG_CONTENT_INFO_TEXT_SIZE : null, fontFamilyConfigAvailable ? PartnerConfig.CONFIG_CONTENT_INFO_FONT_FAMILY : null, + linkFontFamilyConfigAvailable + ? PartnerConfig.CONFIG_DESCRIPTION_LINK_FONT_FAMILY + : null, null, null, 0)); @@ -183,13 +192,11 @@ public final class ContentStyler { // 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); - } + if (PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_START)) { + result = + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_LAYOUT_MARGIN_START, result); } return result; } diff --git a/main/src/com/google/android/setupdesign/util/DescriptionStyler.java b/main/src/com/google/android/setupdesign/util/DescriptionStyler.java index 0a786c6..b779bc6 100644 --- a/main/src/com/google/android/setupdesign/util/DescriptionStyler.java +++ b/main/src/com/google/android/setupdesign/util/DescriptionStyler.java @@ -41,6 +41,7 @@ public final class DescriptionStyler { PartnerConfig.CONFIG_DESCRIPTION_LINK_TEXT_COLOR, PartnerConfig.CONFIG_DESCRIPTION_TEXT_SIZE, PartnerConfig.CONFIG_DESCRIPTION_FONT_FAMILY, + PartnerConfig.CONFIG_DESCRIPTION_LINK_FONT_FAMILY, null, null, PartnerStyleHelper.getLayoutGravity(description.getContext()))); @@ -62,6 +63,7 @@ public final class DescriptionStyler { null, null, null, + null, PartnerStyleHelper.getLayoutGravity(description.getContext()))); } diff --git a/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java b/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java index 2db8c75..654f927 100644 --- a/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java +++ b/main/src/com/google/android/setupdesign/util/DynamicColorPalette.java @@ -19,7 +19,6 @@ package com.google.android.setupdesign.util; import android.content.Context; import androidx.annotation.ColorInt; import androidx.annotation.IntDef; -import androidx.annotation.VisibleForTesting; import com.google.android.setupdesign.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -27,7 +26,7 @@ import java.lang.annotation.RetentionPolicy; /** The class to get dynamic colors. */ public final class DynamicColorPalette { - @VisibleForTesting static int colorRes = 0; + private static int colorRes = 0; private DynamicColorPalette() {} diff --git a/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java b/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java index 1b3daac..e233219 100644 --- a/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java +++ b/main/src/com/google/android/setupdesign/util/HeaderAreaStyler.java @@ -19,6 +19,7 @@ package com.google.android.setupdesign.util; import static com.google.android.setupcompat.util.BuildCompatUtils.isAtLeastS; import android.content.Context; +import android.graphics.drawable.Drawable; import android.graphics.drawable.VectorDrawable; import android.os.Build; import android.os.Build.VERSION; @@ -30,12 +31,14 @@ import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ImageView.ScaleType; +import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; 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; /** @@ -51,11 +54,11 @@ public final class HeaderAreaStyler { "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}. + * Applies the partner style of header text to the given textView {@code header}. * - * @param header A header text would apply partner heavy style + * @param header A header text would apply partner style */ - public static void applyPartnerCustomizationHeaderHeavyStyle(@Nullable TextView header) { + public static void applyPartnerCustomizationHeaderStyle(@Nullable TextView header) { if (header == null) { return; @@ -67,6 +70,7 @@ public final class HeaderAreaStyler { null, PartnerConfig.CONFIG_HEADER_TEXT_SIZE, PartnerConfig.CONFIG_HEADER_FONT_FAMILY, + null, PartnerConfig.CONFIG_HEADER_TEXT_MARGIN_TOP, PartnerConfig.CONFIG_HEADER_TEXT_MARGIN_BOTTOM, PartnerStyleHelper.getLayoutGravity(header.getContext()))); @@ -90,59 +94,13 @@ public final class HeaderAreaStyler { PartnerConfig.CONFIG_DESCRIPTION_LINK_TEXT_COLOR, PartnerConfig.CONFIG_DESCRIPTION_TEXT_SIZE, PartnerConfig.CONFIG_DESCRIPTION_FONT_FAMILY, + PartnerConfig.CONFIG_DESCRIPTION_LINK_FONT_FAMILY, PartnerConfig.CONFIG_DESCRIPTION_TEXT_MARGIN_TOP, PartnerConfig.CONFIG_DESCRIPTION_TEXT_MARGIN_BOTTOM, PartnerStyleHelper.getLayoutGravity(description.getContext()))); } /** - * Applies the partner light style of header text to the given textView {@code header}. - * - * @param header A header text would apply partner light style - */ - public static void applyPartnerCustomizationHeaderLightStyle(@Nullable TextView header) { - - if (header == null) { - return; - } - - TextViewPartnerStyler.applyPartnerCustomizationLightStyle( - header, - new TextPartnerConfigs( - null, - null, - null, - null, - null, - null, - PartnerStyleHelper.getLayoutGravity(header.getContext()))); - } - - /** - * Applies the partner light style of description text to the given textView {@code description}. - * - * @param description A description text would apply partner light style - */ - public static void applyPartnerCustomizationDescriptionLightStyle( - @Nullable TextView description) { - - if (description == null) { - return; - } - - TextViewPartnerStyler.applyPartnerCustomizationLightStyle( - description, - new TextPartnerConfigs( - null, - null, - null, - null, - null, - null, - PartnerStyleHelper.getLayoutGravity(description.getContext()))); - } - - /** * Applies the partner style of header area to the given layout {@code headerArea}. The theme * should set partner heavy theme first, and then the partner style of header would be applied. As * for the margin bottom of header, it would also be appied when heavy theme parter config is @@ -154,34 +112,72 @@ public final class HeaderAreaStyler { if (headerArea == null) { return; } - if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(headerArea)) { - Context context = headerArea.getContext(); - int color = - PartnerConfigHelper.get(context) - .getColor(context, PartnerConfig.CONFIG_HEADER_AREA_BACKGROUND_COLOR); - headerArea.setBackgroundColor(color); + Context context = headerArea.getContext(); + int color = + PartnerConfigHelper.get(context) + .getColor(context, PartnerConfig.CONFIG_HEADER_AREA_BACKGROUND_COLOR); + headerArea.setBackgroundColor(color); + + if (PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_HEADER_CONTAINER_MARGIN_BOTTOM)) { + final ViewGroup.LayoutParams lp = headerArea.getLayoutParams(); + if (lp instanceof ViewGroup.MarginLayoutParams) { + final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) lp; + int bottomMargin = + (int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_HEADER_CONTAINER_MARGIN_BOTTOM); + mlp.setMargins(mlp.leftMargin, mlp.topMargin, mlp.rightMargin, bottomMargin); + headerArea.setLayoutParams(lp); + } + } + } + + public static void applyPartnerCustomizationProgressBarStyle(@Nullable ProgressBar progressBar) { + if (progressBar == null) { + return; + } + Context context = progressBar.getContext(); + final ViewGroup.LayoutParams lp = progressBar.getLayoutParams(); + + if (lp instanceof ViewGroup.MarginLayoutParams) { + final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) lp; + int marginTop = mlp.topMargin; if (PartnerConfigHelper.get(context) - .isPartnerConfigAvailable(PartnerConfig.CONFIG_HEADER_CONTAINER_MARGIN_BOTTOM)) { - final ViewGroup.LayoutParams lp = headerArea.getLayoutParams(); - if (lp instanceof ViewGroup.MarginLayoutParams) { - final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) lp; + .isPartnerConfigAvailable(PartnerConfig.CONFIG_PROGRESS_BAR_MARGIN_TOP)) { + marginTop = + (int) + PartnerConfigHelper.get(context) + .getDimension( + context, + PartnerConfig.CONFIG_PROGRESS_BAR_MARGIN_TOP, + context.getResources().getDimension(R.dimen.sud_progress_bar_margin_top)); + } + int marginBottom = mlp.bottomMargin; + if (PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_PROGRESS_BAR_MARGIN_BOTTOM)) { + marginBottom = + (int) + PartnerConfigHelper.get(context) + .getDimension( + context, + PartnerConfig.CONFIG_PROGRESS_BAR_MARGIN_BOTTOM, + context + .getResources() + .getDimension(R.dimen.sud_progress_bar_margin_bottom)); + } - int bottomMargin = - (int) - PartnerConfigHelper.get(context) - .getDimension(context, PartnerConfig.CONFIG_HEADER_CONTAINER_MARGIN_BOTTOM); - mlp.setMargins(mlp.leftMargin, mlp.topMargin, mlp.rightMargin, bottomMargin); - headerArea.setLayoutParams(lp); - } + if (marginTop != mlp.topMargin || marginBottom != mlp.bottomMargin) { + mlp.setMargins(mlp.leftMargin, marginTop, mlp.rightMargin, marginBottom); } } } /** - * Applies the partner heavy style of header icon to the given {@code iconImage}. The theme should - * check partner heavy theme first, and then the partner icon size would be applied. + * Applies the partner style of header icon to the given {@code iconImage}. It needs to check if + * it should apply partner resource first, and then the partner icon size would be applied. * * @param iconImage A ImageView would apply the partner style of header icon * @param iconContainer The container of the header icon @@ -193,46 +189,48 @@ public final class HeaderAreaStyler { } Context context = iconImage.getContext(); + int reducedIconHeight = 0; int gravity = PartnerStyleHelper.getLayoutGravity(context); if (gravity != 0) { setGravity(iconImage, gravity); } - final ViewGroup.LayoutParams lp = iconContainer.getLayoutParams(); - boolean partnerConfigAvailable = - PartnerConfigHelper.get(context) - .isPartnerConfigAvailable(PartnerConfig.CONFIG_ICON_MARGIN_TOP); - if (partnerConfigAvailable && lp instanceof ViewGroup.MarginLayoutParams) { - final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) lp; - int topMargin = - (int) - PartnerConfigHelper.get(context) - .getDimension(context, PartnerConfig.CONFIG_ICON_MARGIN_TOP); - mlp.setMargins(mlp.leftMargin, topMargin, mlp.rightMargin, mlp.bottomMargin); - } - if (PartnerConfigHelper.get(context).isPartnerConfigAvailable(PartnerConfig.CONFIG_ICON_SIZE)) { - checkImageType(iconImage); final ViewGroup.LayoutParams lpIcon = iconImage.getLayoutParams(); + lpIcon.height = (int) PartnerConfigHelper.get(context) .getDimension(context, PartnerConfig.CONFIG_ICON_SIZE); + lpIcon.width = LayoutParams.WRAP_CONTENT; iconImage.setScaleType(ScaleType.FIT_CENTER); - } - } - /** Applies the partner light style of header icon to the given {@code iconImage}. */ - public static void applyPartnerCustomizationIconStyle(@Nullable ImageView iconImage) { - if (iconImage == null) { - return; + Drawable drawable = iconImage.getDrawable(); + if (drawable != null && drawable.getIntrinsicWidth() > (2 * drawable.getIntrinsicHeight())) { + int fixedIconHeight = + (int) context.getResources().getDimension(R.dimen.sud_horizontal_icon_height); + if (lpIcon.height > fixedIconHeight) { + reducedIconHeight = lpIcon.height - fixedIconHeight; + lpIcon.height = fixedIconHeight; + } + } } - int gravity = PartnerStyleHelper.getLayoutGravity(iconImage.getContext()); - if (gravity != 0) { - setGravity(iconImage, gravity); + + final ViewGroup.LayoutParams lp = iconContainer.getLayoutParams(); + boolean partnerConfigAvailable = + PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(PartnerConfig.CONFIG_ICON_MARGIN_TOP); + if (partnerConfigAvailable && lp instanceof ViewGroup.MarginLayoutParams) { + final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) lp; + int topMargin = + (int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_ICON_MARGIN_TOP); + topMargin += reducedIconHeight; + mlp.setMargins(mlp.leftMargin, topMargin, mlp.rightMargin, mlp.bottomMargin); } } diff --git a/main/src/com/google/android/setupdesign/util/ItemStyler.java b/main/src/com/google/android/setupdesign/util/ItemStyler.java index ecddfd4..5dbf0a4 100644 --- a/main/src/com/google/android/setupdesign/util/ItemStyler.java +++ b/main/src/com/google/android/setupdesign/util/ItemStyler.java @@ -95,6 +95,7 @@ public final class ItemStyler { PartnerConfig.CONFIG_ITEMS_TITLE_FONT_FAMILY, null, null, + null, PartnerStyleHelper.getLayoutGravity(titleTextView.getContext()))); } @@ -116,6 +117,7 @@ public final class ItemStyler { null, PartnerConfig.CONFIG_ITEMS_SUMMARY_TEXT_SIZE, PartnerConfig.CONFIG_ITEMS_SUMMARY_FONT_FAMILY, + null, PartnerConfig.CONFIG_ITEMS_SUMMARY_MARGIN_TOP, null, PartnerStyleHelper.getLayoutGravity(summaryTextView.getContext()))); diff --git a/main/src/com/google/android/setupdesign/util/LayoutStyler.java b/main/src/com/google/android/setupdesign/util/LayoutStyler.java index b707521..b910601 100644 --- a/main/src/com/google/android/setupdesign/util/LayoutStyler.java +++ b/main/src/com/google/android/setupdesign/util/LayoutStyler.java @@ -16,6 +16,8 @@ package com.google.android.setupdesign.util; +import static java.lang.Math.max; + import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; @@ -52,7 +54,9 @@ public final class LayoutStyler { PartnerConfigHelper.get(context) .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_END); - if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(view) + // TODO: After all users added the check before calling the API, this check can be + // deleted. + if (PartnerStyleHelper.shouldApplyPartnerResource(view) && (partnerMarginStartAvailable || partnerMarginEndAvailable)) { int paddingStart; int paddingEnd; @@ -101,7 +105,9 @@ public final class LayoutStyler { PartnerConfigHelper.get(context) .isPartnerConfigAvailable(PartnerConfig.CONFIG_LAYOUT_MARGIN_END); - if (PartnerStyleHelper.shouldApplyPartnerHeavyThemeResource(view) + // TODO: After all users added the check before calling the API, this check can be + // deleted. + if (PartnerStyleHelper.shouldApplyPartnerResource(view) && (partnerMarginStartAvailable || partnerMarginEndAvailable)) { int extraPaddingStart; int extraPaddingEnd; @@ -114,20 +120,24 @@ public final class LayoutStyler { if (partnerMarginStartAvailable) { extraPaddingStart = - ((int) - PartnerConfigHelper.get(context) - .getDimension(context, PartnerConfig.CONFIG_LAYOUT_MARGIN_START)) - - layoutMarginStart; + max( + 0, + ((int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_LAYOUT_MARGIN_START)) + - layoutMarginStart); } else { extraPaddingStart = view.getPaddingStart(); } if (partnerMarginEndAvailable) { extraPaddingEnd = - ((int) - PartnerConfigHelper.get(context) - .getDimension(context, PartnerConfig.CONFIG_LAYOUT_MARGIN_END)) - - layoutMarginEnd; + max( + 0, + ((int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_LAYOUT_MARGIN_END)) + - layoutMarginEnd); } else { extraPaddingEnd = view.getPaddingEnd(); } diff --git a/main/src/com/google/android/setupdesign/util/TextViewPartnerStyler.java b/main/src/com/google/android/setupdesign/util/TextViewPartnerStyler.java index 7b4acea..b56d09a 100644 --- a/main/src/com/google/android/setupdesign/util/TextViewPartnerStyler.java +++ b/main/src/com/google/android/setupdesign/util/TextViewPartnerStyler.java @@ -26,6 +26,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.setupcompat.partnerconfig.PartnerConfig; import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; +import com.google.android.setupdesign.view.RichTextView; /** Helper class to apply partner configurations to a textView. */ final class TextViewPartnerStyler { @@ -85,8 +86,44 @@ final class TextViewPartnerStyler { } } + if (textView instanceof RichTextView && textPartnerConfigs.getLinkTextFontFamilyConfig() != null + && PartnerConfigHelper.get(context) + .isPartnerConfigAvailable(textPartnerConfigs.getLinkTextFontFamilyConfig())) { + String linkFontFamilyName = + PartnerConfigHelper.get(context) + .getString(context, textPartnerConfigs.getLinkTextFontFamilyConfig()); + Typeface linkFont = Typeface.create(linkFontFamilyName, Typeface.NORMAL); + if (linkFont != null) { + ((RichTextView) textView).setSpanTypeface(linkFont); + } + } + + applyPartnerCustomizationVerticalMargins(textView, textPartnerConfigs); + textView.setGravity(textPartnerConfigs.getTextGravity()); + } + + /** + * Applies given partner configurations {@code textPartnerConfigs} to the {@code textView}. + * + * @param textView A text view would apply the gravity + * @param textPartnerConfigs A partner conflagrations contains text gravity would be set + */ + public static void applyPartnerCustomizationLightStyle( + @NonNull TextView textView, @NonNull TextPartnerConfigs textPartnerConfigs) { + + if (textView == null || textPartnerConfigs == null) { + return; + } + + applyPartnerCustomizationVerticalMargins(textView, textPartnerConfigs); + textView.setGravity(textPartnerConfigs.getTextGravity()); + } + + private static void applyPartnerCustomizationVerticalMargins( + @NonNull TextView textView, @NonNull TextPartnerConfigs textPartnerConfigs) { if (textPartnerConfigs.getTextMarginTop() != null || textPartnerConfigs.getTextMarginBottom() != null) { + Context context = textView.getContext(); int topMargin; int bottomMargin; final ViewGroup.LayoutParams lp = textView.getLayoutParams(); @@ -117,23 +154,6 @@ final class TextViewPartnerStyler { textView.setLayoutParams(lp); } } - textView.setGravity(textPartnerConfigs.getTextGravity()); - } - - /** - * Applies given partner configurations {@code textPartnerConfigs} to the {@code textView}. - * - * @param textView A text view would apply the gravity - * @param textPartnerConfigs A partner conflagrations contains text gravity would be set - */ - public static void applyPartnerCustomizationLightStyle( - @NonNull TextView textView, @NonNull TextPartnerConfigs textPartnerConfigs) { - - if (textView == null || textPartnerConfigs == null) { - return; - } - - textView.setGravity(textPartnerConfigs.getTextGravity()); } /** Keeps the partner conflagrations for a textView. */ @@ -142,6 +162,7 @@ final class TextViewPartnerStyler { private final PartnerConfig textLinkedColorConfig; private final PartnerConfig textSizeConfig; private final PartnerConfig textFontFamilyConfig; + private final PartnerConfig textLinkFontFamilyConfig; private final PartnerConfig textMarginTopConfig; private final PartnerConfig textMarginBottomConfig; private final int textGravity; @@ -151,6 +172,7 @@ final class TextViewPartnerStyler { @Nullable PartnerConfig textLinkedColorConfig, @Nullable PartnerConfig textSizeConfig, @Nullable PartnerConfig textFontFamilyConfig, + @Nullable PartnerConfig textLinkFontFamilyConfig, @Nullable PartnerConfig textMarginTopConfig, @Nullable PartnerConfig textMarginBottomConfig, int textGravity) { @@ -158,6 +180,7 @@ final class TextViewPartnerStyler { this.textLinkedColorConfig = textLinkedColorConfig; this.textSizeConfig = textSizeConfig; this.textFontFamilyConfig = textFontFamilyConfig; + this.textLinkFontFamilyConfig = textLinkFontFamilyConfig; this.textMarginTopConfig = textMarginTopConfig; this.textMarginBottomConfig = textMarginBottomConfig; this.textGravity = textGravity; @@ -179,6 +202,10 @@ final class TextViewPartnerStyler { return textFontFamilyConfig; } + public PartnerConfig getLinkTextFontFamilyConfig() { + return textLinkFontFamilyConfig; + } + public PartnerConfig getTextMarginTop() { return textMarginTopConfig; } diff --git a/main/src/com/google/android/setupdesign/util/ThemeHelper.java b/main/src/com/google/android/setupdesign/util/ThemeHelper.java index 0b750c9..3c46be9 100644 --- a/main/src/com/google/android/setupdesign/util/ThemeHelper.java +++ b/main/src/com/google/android/setupdesign/util/ThemeHelper.java @@ -166,16 +166,9 @@ public final class ThemeHelper { return PartnerConfigHelper.shouldApplyExtendedPartnerConfig(context); } - /** - * Returns {@code true} if the partner provider of SetupWizard is ready to support dynamic color. - */ - public static boolean isSetupWizardDynamicColorEnabled(@NonNull Context context) { - return PartnerConfigHelper.isSetupWizardDynamicColorEnabled(context); - } - /** Returns {@code true} if this {@code context} should apply dynamic color. */ public static boolean shouldApplyDynamicColor(@NonNull Context context) { - return shouldApplyExtendedPartnerConfig(context) && isSetupWizardDynamicColorEnabled(context); + return PartnerConfigHelper.isSetupWizardDynamicColorEnabled(context); } /** @@ -237,12 +230,12 @@ public final class ThemeHelper { /** Returns {@code true} if the dynamic color is set. */ public static boolean trySetDynamicColor(@NonNull Context context) { - if (!shouldApplyExtendedPartnerConfig(context)) { - LOG.w("SetupWizard does not supports the extended partner configs."); + if (!BuildCompatUtils.isAtLeastS()) { + LOG.w("Dynamic color require platform version at least S."); return false; } - if (!isSetupWizardDynamicColorEnabled(context)) { + if (!shouldApplyDynamicColor(context)) { LOG.w("SetupWizard does not support the dynamic color or supporting status unknown."); return false; } diff --git a/main/src/com/google/android/setupdesign/view/IntrinsicSizeFrameLayout.java b/main/src/com/google/android/setupdesign/view/IntrinsicSizeFrameLayout.java index d02839b..4094f3a 100644 --- a/main/src/com/google/android/setupdesign/view/IntrinsicSizeFrameLayout.java +++ b/main/src/com/google/android/setupdesign/view/IntrinsicSizeFrameLayout.java @@ -16,13 +16,21 @@ package com.google.android.setupdesign.view; +import static java.lang.Math.min; + import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; +import android.graphics.Rect; +import android.os.Build; import android.os.Build.VERSION_CODES; import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.Display; import android.view.ViewGroup; +import android.view.WindowInsets; import android.widget.FrameLayout; +import androidx.annotation.VisibleForTesting; import com.google.android.setupcompat.partnerconfig.PartnerConfig; import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; import com.google.android.setupcompat.util.BuildCompatUtils; @@ -40,6 +48,10 @@ public class IntrinsicSizeFrameLayout extends FrameLayout { private int intrinsicHeight = 0; private int intrinsicWidth = 0; + private Object lastInsets; // Use generic Object type for compatibility + + // Define here to avoid allocating resource during layout/draw operation. + private final Rect windowVisibleDisplayRect = new Rect(); public IntrinsicSizeFrameLayout(Context context) { super(context); @@ -105,9 +117,43 @@ public class IntrinsicSizeFrameLayout extends FrameLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure( - getIntrinsicMeasureSpec(widthMeasureSpec, intrinsicWidth), - getIntrinsicMeasureSpec(heightMeasureSpec, intrinsicHeight)); + int measureWidth; + + // The the content may be truncated if the layout show in multi-window mode or two pane mode, + // because the given width is fixed size which based on the display to compute. So the width + // the content may be truncated. Make the layout width align window while window width smaller + // than display size. + if (isWindowSizeSmallerThanDisplaySize()) { + getWindowVisibleDisplayFrame(windowVisibleDisplayRect); + + measureWidth = + MeasureSpec.makeMeasureSpec(windowVisibleDisplayRect.width(), MeasureSpec.EXACTLY); + } else { + measureWidth = getIntrinsicMeasureSpec(widthMeasureSpec, intrinsicWidth); + } + + super.onMeasure(measureWidth, getIntrinsicMeasureSpec(heightMeasureSpec, intrinsicHeight)); + } + + @VisibleForTesting + boolean isWindowSizeSmallerThanDisplaySize() { + boolean result = false; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + getWindowVisibleDisplayFrame(windowVisibleDisplayRect); + + Display display = getDisplay(); + if (display != null) { + DisplayMetrics displayMetrics = new DisplayMetrics(); + display.getRealMetrics(displayMetrics); + + if (windowVisibleDisplayRect.width() > 0 + && windowVisibleDisplayRect.width() < displayMetrics.widthPixels) { + result = true; + } + } + } + + return result; } private int getIntrinsicMeasureSpec(int measureSpec, int intrinsicSize) { @@ -123,9 +169,25 @@ public class IntrinsicSizeFrameLayout extends FrameLayout { } else if (mode == MeasureSpec.AT_MOST) { // If intrinsic size is within parents constraint, take the intrinsic size. // Otherwise take the parents size because that's closest to the intrinsic size. - return MeasureSpec.makeMeasureSpec(Math.min(size, intrinsicHeight), MeasureSpec.EXACTLY); + return MeasureSpec.makeMeasureSpec(min(size, intrinsicHeight), MeasureSpec.EXACTLY); } // Parent specified EXACTLY, or in all other cases, just return the original spec return measureSpec; } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + if (lastInsets == null) { + requestApplyInsets(); + } + } + } + + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + lastInsets = insets; + return super.onApplyWindowInsets(insets); + } } diff --git a/main/src/com/google/android/setupdesign/view/RichTextView.java b/main/src/com/google/android/setupdesign/view/RichTextView.java index f3348b4..182981f 100644 --- a/main/src/com/google/android/setupdesign/view/RichTextView.java +++ b/main/src/com/google/android/setupdesign/view/RichTextView.java @@ -16,11 +16,13 @@ package com.google.android.setupdesign.view; +import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.content.Context; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; -import androidx.core.view.ViewCompat; import androidx.appcompat.widget.AppCompatTextView; import android.text.Annotation; import android.text.SpannableString; @@ -32,6 +34,8 @@ import android.text.style.TypefaceSpan; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; +import androidx.annotation.VisibleForTesting; +import androidx.core.view.ViewCompat; import com.google.android.setupdesign.accessibility.LinkAccessibilityHelper; import com.google.android.setupdesign.span.LinkSpan; import com.google.android.setupdesign.span.LinkSpan.OnLinkClickListener; @@ -51,6 +55,8 @@ public class RichTextView extends AppCompatTextView implements OnLinkClickListen private static final String ANNOTATION_LINK = "link"; private static final String ANNOTATION_TEXT_APPEARANCE = "textAppearance"; + @VisibleForTesting static Typeface spanTypeface; + /** * Replace <annotation> tags in strings to become their respective types. Currently 2 types * are supported: @@ -62,6 +68,8 @@ public class RichTextView extends AppCompatTextView implements OnLinkClickListen * android.text.style.TextAppearanceSpan} with @style/TextAppearance.FooBar * </ol> */ + @TargetApi(28) + @SuppressLint("NewApi") public static CharSequence getRichText(Context context, CharSequence text) { if (text instanceof Spanned) { final SpannableString spannable = new SpannableString(text); @@ -81,7 +89,10 @@ public class RichTextView extends AppCompatTextView implements OnLinkClickListen SpanHelper.replaceSpan(spannable, span, textAppearanceSpan); } else if (ANNOTATION_LINK.equals(key)) { LinkSpan link = new LinkSpan(span.getValue()); - TypefaceSpan typefaceSpan = new TypefaceSpan("sans-serif-medium"); + TypefaceSpan typefaceSpan = + (spanTypeface != null) + ? new TypefaceSpan(spanTypeface) + : new TypefaceSpan("sans-serif-medium"); SpanHelper.replaceSpan(spannable, span, link, typefaceSpan); } } @@ -114,6 +125,17 @@ public class RichTextView extends AppCompatTextView implements OnLinkClickListen ViewCompat.setAccessibilityDelegate(this, accessibilityHelper); } + /** + * Sets the typeface in which the text should be displayed. The default typeface is {@code + * "sans-serif-medium"} + * + * @throws java.lang.NoSuchMethodError if sdk lower than {@code VERSION_CODES.P} + */ + @TargetApi(VERSION_CODES.P) + public void setSpanTypeface(Typeface typeface) { + spanTypeface = typeface; + } + @Override public void setText(CharSequence text, BufferType type) { text = getRichText(getContext(), text); diff --git a/strings/AndroidManifest.xml b/strings/AndroidManifest.xml index e8316f3..c323fc7 100644 --- a/strings/AndroidManifest.xml +++ b/strings/AndroidManifest.xml @@ -20,6 +20,6 @@ <uses-sdk android:minSdkVersion="14" - android:targetSdkVersion="28" /> + android:targetSdkVersion="31" /> </manifest> |