diff options
author | Setup Wizard Team <android-setup-team-eng@google.com> | 2021-03-17 15:09:32 +0800 |
---|---|---|
committer | Pasty Chang <pastychang@google.com> | 2021-03-17 07:16:47 +0000 |
commit | 6b505d9b7717dc5afd442df1b5665b6dd47df9fb (patch) | |
tree | 6ec3ca9240494f890d45de3ea8009a1441168f0b | |
parent | 99993f10df91c854e746d6bc7b08ffb94e991037 (diff) | |
download | setupdesign-6b505d9b7717dc5afd442df1b5665b6dd47df9fb.tar.gz |
Import updated Android Setupdesign Library 363357645
Copied from google3/third_party/java_src/android_libs/setupdesign
Test: mm
Bug: 182136477
Included changes:
- 363357645 [SetupDesign] ThemeHelper.applyTheme need to consider if ...
- 363128601 Fix exception when setDescriptionText with a invalid reso...
- 362493931 Add API to hide Header area in landscape screen
- 362449370 [GlifLoadingLayout] Fix content name incorrect, Foward AP...
- 362400099 [GlifLoadingLayout] Should check is animation still playi...
- 362261179 Update the height of footer bar and footer button in land...
- 361952275 Automated g4 rollback of changelist 361035807.
- 361499610 [GlifLoadingLayout] Add light theme customization, we sho...
- 361490731 [GlifLoadingLayout] Extract FillContentLayout maxWidth/ma...
- 361470484 Judge ui mode is night from activity resource instead of ...
- 361049392 [SetupDesign] update the command for glifv4; not removed ...
- 361035807 Use different weight values for two columns landscape lay...
PiperOrigin-RevId: 363357645
Change-Id: Ia94d4f1e7d16b20d3232ccec05b3367c38c37774
22 files changed, 1088 insertions, 16 deletions
diff --git a/lottie_loading_layout/AndroidManifest.xml b/lottie_loading_layout/AndroidManifest.xml new file mode 100644 index 0000000..3cf1948 --- /dev/null +++ b/lottie_loading_layout/AndroidManifest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2020 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.setupdesign.lottieloadinglayout"> + + <uses-sdk + android:minSdkVersion="14" + android:targetSdkVersion="30" /> + +</manifest> diff --git a/lottie_loading_layout/res/layout-land-v31/sud_glif_loading_template_content.xml b/lottie_loading_layout/res/layout-land-v31/sud_glif_loading_template_content.xml new file mode 100644 index 0000000..0e0e945 --- /dev/null +++ b/lottie_loading_layout/res/layout-land-v31/sud_glif_loading_template_content.xml @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android: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/suc_landscape_header_area" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + 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:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:orientation="vertical"> + + <com.google.android.setupdesign.view.BottomScrollView + android:id="@+id/sud_scroll_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fillViewport="true" + android:scrollIndicators="?attr/sudScrollIndicators"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <ViewStub + android:id="@+id/sud_loading_layout_illustration_stub" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:inflatedId="@+id/sud_layout_progress_illustration" + android:layout="@layout/sud_loading_illustration_layout" /> + + <ViewStub + android:id="@+id/sud_loading_layout_lottie_stub" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:inflatedId="@+id/sud_layout_lottie_illustration" + android:layout="@layout/sud_loading_lottie_layout" /> + + <FrameLayout + android:id="@+id/sud_layout_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" /> + + </LinearLayout> + + </com.google.android.setupdesign.view.BottomScrollView> + + </LinearLayout> + + </LinearLayout> + + <ViewStub + android:id="@+id/suc_layout_footer" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + +</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 new file mode 100644 index 0000000..86003b9 --- /dev/null +++ b/lottie_loading_layout/res/layout/sud_glif_loading_template_compat.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. +--> + +<com.google.android.setupcompat.view.StatusBarBackgroundLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/suc_layout_status" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <include layout="@layout/sud_glif_loading_template_content" /> + +</com.google.android.setupcompat.view.StatusBarBackgroundLayout>
\ No newline at end of file diff --git a/lottie_loading_layout/res/layout/sud_glif_loading_template_content.xml b/lottie_loading_layout/res/layout/sud_glif_loading_template_content.xml new file mode 100644 index 0000000..7b00e7f --- /dev/null +++ b/lottie_loading_layout/res/layout/sud_glif_loading_template_content.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android: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" /> + + <!-- Ignore UnusedAttribute: scrollIndicators is new in M. Default to no indicators in older + versions. --> + <com.google.android.setupdesign.view.BottomScrollView + android:id="@+id/sud_scroll_view" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:fillViewport="true" + android:scrollIndicators="?attr/sudScrollIndicators" + tools:ignore="UnusedAttribute"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <include layout="@layout/sud_glif_header" /> + + <ViewStub + android:id="@+id/sud_loading_layout_illustration_stub" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:inflatedId="@+id/sud_layout_progress_illustration" + android:layout="@layout/sud_loading_illustration_layout" /> + + <ViewStub + android:id="@+id/sud_loading_layout_lottie_stub" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:inflatedId="@+id/sud_layout_lottie_illustration" + android:layout="@layout/sud_loading_lottie_layout" /> + + <FrameLayout + android:id="@+id/sud_layout_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" /> + + </LinearLayout> + + </com.google.android.setupdesign.view.BottomScrollView> + + + <ViewStub + android:id="@+id/suc_layout_footer" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + +</LinearLayout> diff --git a/lottie_loading_layout/res/layout/sud_loading_illustration_layout.xml b/lottie_loading_layout/res/layout/sud_loading_illustration_layout.xml new file mode 100644 index 0000000..772598e --- /dev/null +++ b/lottie_loading_layout/res/layout/sud_loading_illustration_layout.xml @@ -0,0 +1,46 @@ +<?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" + style="@style/SudContentFrame" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <com.google.android.setupdesign.view.FillContentLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ProgressBar + android:id="@+id/sud_progress_bar" + android:visibility="gone" + style="@style/SudFourColorIndeterminateProgressBar" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <com.google.android.setupdesign.view.IllustrationVideoView + android:id="@+id/sud_progress_illustration" + android:visibility="gone" + style="@style/SudContentIllustration" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </com.google.android.setupdesign.view.FillContentLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/lottie_loading_layout/res/layout/sud_loading_lottie_layout.xml b/lottie_loading_layout/res/layout/sud_loading_lottie_layout.xml new file mode 100644 index 0000000..2ca2c28 --- /dev/null +++ b/lottie_loading_layout/res/layout/sud_loading_lottie_layout.xml @@ -0,0 +1,41 @@ +<?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" + style="@style/SudContentFrame" + android:layout_width="match_parent" + android:layout_height="match_parent" > + + <com.google.android.setupdesign.view.FillContentLayout + android:orientation="vertical" + 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" + style="@style/SudContentIllustration" + app:lottie_autoPlay="false" + app:lottie_loop="true" /> + + </com.google.android.setupdesign.view.FillContentLayout> + +</LinearLayout> diff --git a/lottie_loading_layout/res/values/attrs.xml b/lottie_loading_layout/res/values/attrs.xml new file mode 100644 index 0000000..a011ac1 --- /dev/null +++ b/lottie_loading_layout/res/values/attrs.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. +--> + +<resources> + <declare-styleable name="SudGlifLoadingLayout"> + <attr name="sudIllustrationType" format="string" /> + <attr name="sudLottieRes" format="reference" /> + </declare-styleable> +</resources>
\ No newline at end of file diff --git a/lottie_loading_layout/res/values/layouts.xml b/lottie_loading_layout/res/values/layouts.xml new file mode 100644 index 0000000..483f09d --- /dev/null +++ b/lottie_loading_layout/res/values/layouts.xml @@ -0,0 +1,20 @@ +<?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_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 new file mode 100644 index 0000000..f3b5b98 --- /dev/null +++ b/lottie_loading_layout/src/com/google/android/setupdesign/GlifLoadingLayout.java @@ -0,0 +1,632 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.setupdesign; + +import static com.google.android.setupcompat.partnerconfig.Util.isNightMode; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.os.Build; +import android.os.Build.VERSION_CODES; +import android.os.Bundle; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewStub; +import android.widget.ProgressBar; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RawRes; +import androidx.annotation.StringDef; +import androidx.annotation.VisibleForTesting; +import com.airbnb.lottie.LottieAnimationView; +import com.airbnb.lottie.LottieProperty; +import com.airbnb.lottie.SimpleColorFilter; +import com.airbnb.lottie.model.KeyPath; +import com.airbnb.lottie.value.LottieValueCallback; +import com.airbnb.lottie.value.SimpleLottieValueCallback; +import com.google.android.setupcompat.partnerconfig.PartnerConfig; +import com.google.android.setupcompat.partnerconfig.PartnerConfig.ResourceType; +import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; +import com.google.android.setupcompat.partnerconfig.ResourceEntry; +import com.google.android.setupdesign.lottieloadinglayout.R; +import com.google.android.setupdesign.util.BuildCompatUtils; +import com.google.android.setupdesign.view.IllustrationVideoView; +import java.io.InputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GlifLoadingLayout extends GlifLayout { + private static final String TAG = "GlifLoadingLayout"; + + @VisibleForTesting @IllustrationType String illustrationType = IllustrationType.DEFAULT; + @VisibleForTesting LottieAnimationConfig animationConfig = LottieAnimationConfig.CONFIG_DEFAULT; + + @VisibleForTesting @RawRes int customLottieResource = 0; + + @VisibleForTesting Map<KeyPath, SimpleColorFilter> customizationMap = new HashMap<>(); + + @VisibleForTesting LottieAnimationFinishListener animationFinishListener; + + public GlifLoadingLayout(Context context) { + this(context, 0, 0); + } + + public GlifLoadingLayout(Context context, int template) { + this(context, template, 0); + } + + public GlifLoadingLayout(Context context, int template, int containerId) { + super(context, template, containerId); + init(null, R.attr.sudLayoutTheme); + } + + public GlifLoadingLayout(Context context, AttributeSet attrs) { + super(context, attrs); + init(attrs, R.attr.sudLayoutTheme); + } + + @TargetApi(VERSION_CODES.HONEYCOMB) + public GlifLoadingLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(attrs, defStyleAttr); + } + + private void init(AttributeSet attrs, int defStyleAttr) { + TypedArray a = + getContext() + .obtainStyledAttributes(attrs, R.styleable.SudGlifLoadingLayout, defStyleAttr, 0); + customLottieResource = a.getResourceId(R.styleable.SudGlifLoadingLayout_sudLottieRes, 0); + String illustrationType = a.getString(R.styleable.SudGlifLoadingLayout_sudIllustrationType); + a.recycle(); + if (customLottieResource != 0) { + inflateLottieView(); + ViewGroup container = findContainer(0); + container.setVisibility(View.VISIBLE); + } else { + if (illustrationType != null) { + setIllustrationType(illustrationType); + } + + if (BuildCompatUtils.isAtLeastS()) { + inflateLottieView(); + } else { + inflateIllustrationStub(); + } + } + } + + public void setIllustrationType(@IllustrationType String type) { + if (customLottieResource != 0) { + throw new IllegalStateException( + "custom illustration already applied, should not set illustration."); + } + + if (!illustrationType.equals(type)) { + illustrationType = type; + customizationMap.clear(); + } + + switch (type) { + case IllustrationType.ACCOUNT: + animationConfig = LottieAnimationConfig.CONFIG_ACCOUNT; + break; + + case IllustrationType.CONNECTION: + animationConfig = LottieAnimationConfig.CONFIG_CONNECTION; + break; + + case IllustrationType.UPDATE: + animationConfig = LottieAnimationConfig.CONFIG_UPDATE; + break; + + default: + animationConfig = LottieAnimationConfig.CONFIG_DEFAULT; + break; + } + + updateAnimationView(); + } + + // TODO: [GlifLoadingLayout] Should add testcase. LottieAnimationView was auto + // generated not able to mock. So we have no idea how to detected is the api pass to + // LottiAnimationView correctly. + public boolean setAnimation(InputStream inputStream, String keyCache) { + LottieAnimationView lottieAnimationView = findLottieAnimationView(); + if (lottieAnimationView != null) { + lottieAnimationView.setAnimation(inputStream, keyCache); + return true; + } else { + return false; + } + } + + public boolean setAnimation(String assetName) { + LottieAnimationView lottieAnimationView = findLottieAnimationView(); + if (lottieAnimationView != null) { + lottieAnimationView.setAnimation(assetName); + return true; + } else { + return false; + } + } + + public boolean setAnimation(@RawRes int rawRes) { + LottieAnimationView lottieAnimationView = findLottieAnimationView(); + if (lottieAnimationView != null) { + lottieAnimationView.setAnimation(rawRes); + return true; + } else { + return false; + } + } + + private void updateAnimationView() { + if (BuildCompatUtils.isAtLeastS()) { + setLottieResource(); + } else { + setIllustrationResource(); + } + } + + /** + * Call this when your activity is done and should be closed. The activity will be finished while + * animation finished. + */ + public void finish(@NonNull Activity activity) { + if (activity == null) { + throw new NullPointerException("activity should not be null"); + } + animationFinishListener = + new LottieAnimationFinishListener(findLottieAnimationView()) { + + @Override + void onAnimationFinished() { + activity.finish(); + removeListener(); + } + }; + } + + /** + * Launch a new activity after the animation finished. + * + * @param activity The activity which is GlifLoadingLayout attached to. + * @param intent The intent to start. + * @param options Additional options for how the Activity should be started. See {@link + * android.content.Context#startActivity(Intent, Bundle)} for more details. + * @param finish Finish the activity after startActivity + * @see Activity#startActivity(Intent) + * @see Activity#startActivityForResult + */ + public void startActivity( + @NonNull Activity activity, + @NonNull Intent intent, + @Nullable Bundle options, + boolean finish) { + if (activity == null) { + throw new NullPointerException("activity should not be null"); + } + + if (intent == null) { + throw new NullPointerException("intent should not be null"); + } + + animationFinishListener = + new LottieAnimationFinishListener(findLottieAnimationView()) { + @Override + void onAnimationFinished() { + if (options == null || Build.VERSION.SDK_INT < VERSION_CODES.JELLY_BEAN) { + activity.startActivity(intent); + } else { + activity.startActivity(intent, options); + } + + if (finish) { + activity.finish(); + } + + removeListener(); + } + }; + } + + /** + * Waiting for the animation finished and launch an activity for which you would like a result + * when it finished. + * + * @param activity The activity which the GlifLoadingLayout attached to. + * @param intent The intent to start. + * @param requestCode If >= 0, this code will be returned in onActivityResult() when the activity + * exits. + * @param options Additional options for how the Activity should be started. + * @param finish Finish the activity after startActivityForResult. The onActivityResult might not + * be called because the activity already finixhed. + * <p>See {@link android.content.Context#startActivity(Intent, Bundle)} + * Context.startActivity(Intent, Bundle)} for more details. + */ + public void startActivityForResult( + @NonNull Activity activity, + @NonNull Intent intent, + int requestCode, + @Nullable Bundle options, + boolean finish) { + if (activity == null) { + throw new NullPointerException("activity should not be null"); + } + + if (intent == null) { + throw new NullPointerException("intent should not be null"); + } + + animationFinishListener = + new LottieAnimationFinishListener(findLottieAnimationView()) { + + @Override + void onAnimationFinished() { + if (options == null || Build.VERSION.SDK_INT < VERSION_CODES.JELLY_BEAN) { + activity.startActivityForResult(intent, requestCode); + } else { + activity.startActivityForResult(intent, requestCode, options); + } + + if (finish) { + activity.finish(); + } + removeListener(); + } + }; + } + + private void inflateLottieView() { + final View lottieLayout = peekLottieLayout(); + if (lottieLayout == null) { + ViewStub viewStub = findManagedViewById(R.id.sud_loading_layout_lottie_stub); + if (viewStub != null) { + viewStub.inflate(); + setLottieResource(); + } + } + } + + private void inflateIllustrationStub() { + final View progressLayout = peekProgressIllustrationLayout(); + if (progressLayout == null) { + ViewStub viewStub = findManagedViewById(R.id.sud_loading_layout_illustration_stub); + if (viewStub != null) { + viewStub.inflate(); + setIllustrationResource(); + } + } + } + + private void setLottieResource() { + LottieAnimationView lottieView = findViewById(R.id.sud_lottie_view); + if (lottieView == null) { + Log.w(TAG, "Lottie view not found, skip set resource. Wait for layout inflated."); + return; + } + if (customLottieResource != 0) { + InputStream inputRaw = getResources().openRawResource(customLottieResource); + lottieView.setAnimation(inputRaw, null); + lottieView.playAnimation(); + } else { + PartnerConfigHelper partnerConfigHelper = PartnerConfigHelper.get(getContext()); + ResourceEntry resourceEntry = + partnerConfigHelper.getIllustrationResourceEntry( + getContext(), animationConfig.getLottieConfig()); + + if (resourceEntry != null) { + InputStream inputRaw = + resourceEntry.getResources().openRawResource(resourceEntry.getResourceId()); + lottieView.setAnimation(inputRaw, null); + lottieView.playAnimation(); + setLottieLayoutVisibility(View.VISIBLE); + setIllustrationLayoutVisibility(View.GONE); + applyThemeCustomization(); + } else { + setLottieLayoutVisibility(View.GONE); + setIllustrationLayoutVisibility(View.VISIBLE); + inflateIllustrationStub(); + } + } + } + + private void setIllustrationLayoutVisibility(int visibility) { + View illustrationLayout = findViewById(R.id.sud_layout_progress_illustration); + if (illustrationLayout != null) { + illustrationLayout.setVisibility(visibility); + } + } + + private void setLottieLayoutVisibility(int visibility) { + View lottieLayout = findViewById(R.id.sud_layout_lottie_illustration); + if (lottieLayout != null) { + lottieLayout.setVisibility(visibility); + } + } + + private void setIllustrationResource() { + View illustrationLayout = findViewById(R.id.sud_layout_progress_illustration); + if (illustrationLayout == null) { + Log.i(TAG, "Illustration stub not inflated, skip set resource"); + return; + } + + IllustrationVideoView illustrationVideoView = + findManagedViewById(R.id.sud_progress_illustration); + ProgressBar progressBar = findManagedViewById(R.id.sud_progress_bar); + + PartnerConfigHelper partnerConfigHelper = PartnerConfigHelper.get(getContext()); + ResourceEntry resourceEntry = + partnerConfigHelper.getIllustrationResourceEntry( + getContext(), animationConfig.getIllustrationConfig()); + + if (resourceEntry != null) { + progressBar.setVisibility(GONE); + illustrationVideoView.setVisibility(VISIBLE); + illustrationVideoView.setVideoResourceEntry(resourceEntry); + } else { + progressBar.setVisibility(VISIBLE); + illustrationVideoView.setVisibility(GONE); + } + } + + private LottieAnimationView findLottieAnimationView() { + return findViewById(R.id.sud_lottie_view); + } + + //TODO: Should add testcase with mocked LottieAnimationView. + /** Add an animator listener to {@link LottieAnimationView}. */ + public void addAnimatorListener(Animator.AnimatorListener listener) { + LottieAnimationView animationView = findLottieAnimationView(); + if (animationView != null) { + animationView.addAnimatorListener(listener); + } + } + + /** Remove the listener from {@link LottieAnimationView}. */ + public void removeAnimatorListener(AnimatorListener listener) { + LottieAnimationView animationView = findLottieAnimationView(); + if (animationView != null) { + animationView.removeAnimatorListener(listener); + } + } + + /** Remove all {@link AnimatorListener} from {@link LottieAnimationView}. */ + public void removeAllAnimatorListener() { + LottieAnimationView animationView = findLottieAnimationView(); + if (animationView != null) { + animationView.removeAllAnimatorListeners(); + } + } + + /** Add a value callback with property {@link LottieProperty.COLOR_FILTER}. */ + public void addColorCallback(KeyPath keyPath, LottieValueCallback<ColorFilter> callback) { + LottieAnimationView animationView = findLottieAnimationView(); + if (animationView != null) { + animationView.addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback); + } + } + + /** Add a simple value callback with property {@link LottieProperty.COLOR_FILTER}. */ + public void addColorCallback(KeyPath keyPath, SimpleLottieValueCallback<ColorFilter> callback) { + LottieAnimationView animationView = findLottieAnimationView(); + if (animationView != null) { + animationView.addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback); + } + } + + @VisibleForTesting + protected void loadCustomization() { + if (customizationMap.isEmpty()) { + PartnerConfigHelper helper = PartnerConfigHelper.get(getContext()); + List<String> lists = + helper.getStringArray( + getContext(), + isNightMode(getResources().getConfiguration()) + ? animationConfig.getDarkThemeCustomization() + : animationConfig.getLightThemeCustomization()); + for (String item : lists) { + String[] splitItem = item.split(":"); + if (splitItem.length == 2) { + customizationMap.put( + new KeyPath(splitItem[0]), new SimpleColorFilter(Color.parseColor(splitItem[1]))); + } else { + Log.w(TAG, "incorrect format customization, value=" + item); + } + } + } + } + + @VisibleForTesting + protected void applyThemeCustomization() { + LottieAnimationView animationView = findLottieAnimationView(); + if (animationView != null) { + loadCustomization(); + for (KeyPath keyPath : customizationMap.keySet()) { + animationView.addValueCallback( + keyPath, + LottieProperty.COLOR_FILTER, + new LottieValueCallback<>(customizationMap.get(keyPath))); + } + } + } + + @Nullable + private View peekLottieLayout() { + return findViewById(R.id.sud_layout_lottie_illustration); + } + + @Nullable + private View peekProgressIllustrationLayout() { + return findViewById(R.id.sud_layout_progress_illustration); + } + + @Override + protected View onInflateTemplate(LayoutInflater inflater, int template) { + if (template == 0) { + template = R.layout.sud_glif_loading_template; + } + return inflateTemplate(inflater, R.style.SudThemeGlif_Light, template); + } + + @Override + protected ViewGroup findContainer(int containerId) { + if (containerId == 0) { + containerId = R.id.sud_layout_content; + } + return super.findContainer(containerId); + } + + /** The progress config used to maps to different animation */ + public enum LottieAnimationConfig { + CONFIG_DEFAULT( + PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_DEFAULT, + PartnerConfig.CONFIG_LOADING_LOTTIE_DEFAULT, + PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_DEFAULT, + PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_DEFAULT), + CONFIG_ACCOUNT( + PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_ACCOUNT, + PartnerConfig.CONFIG_LOADING_LOTTIE_ACCOUNT, + PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_ACCOUNT, + PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_ACCOUNT), + CONFIG_CONNECTION( + PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_CONNECTION, + PartnerConfig.CONFIG_LOADING_LOTTIE_CONNECTION, + PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_CONNECTION, + PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_CONNECTION), + CONFIG_UPDATE( + PartnerConfig.CONFIG_PROGRESS_ILLUSTRATION_UPDATE, + PartnerConfig.CONFIG_LOADING_LOTTIE_UPDATE, + PartnerConfig.CONFIG_LOTTIE_LIGHT_THEME_CUSTOMIZATION_UPDATE, + PartnerConfig.CONFIG_LOTTIE_DARK_THEME_CUSTOMIZATION_UPDATE); + + private final PartnerConfig illustrationConfig; + private final PartnerConfig lottieConfig; + private final PartnerConfig lightThemeCustomization; + private final PartnerConfig darkThemeCustomization; + + LottieAnimationConfig( + PartnerConfig illustrationConfig, + PartnerConfig lottieConfig, + PartnerConfig lightThemeCustomization, + PartnerConfig darkThemeCustomization) { + if (illustrationConfig.getResourceType() != ResourceType.ILLUSTRATION + || lottieConfig.getResourceType() != ResourceType.ILLUSTRATION) { + throw new IllegalArgumentException( + "Illustration progress only allow illustration resource"); + } + this.illustrationConfig = illustrationConfig; + this.lottieConfig = lottieConfig; + this.lightThemeCustomization = lightThemeCustomization; + this.darkThemeCustomization = darkThemeCustomization; + } + + PartnerConfig getIllustrationConfig() { + return illustrationConfig; + } + + PartnerConfig getLottieConfig() { + return lottieConfig; + } + + PartnerConfig getLightThemeCustomization() { + return lightThemeCustomization; + } + + PartnerConfig getDarkThemeCustomization() { + return darkThemeCustomization; + } + } + + @VisibleForTesting + abstract class LottieAnimationFinishListener { + + private final LottieAnimationView lottieAnimationView; + + @VisibleForTesting + AnimatorListener animatorListener = + new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + // Do nothing. + } + + @Override + public void onAnimationEnd(Animator animation) { + onAnimationFinished(); + } + + @Override + public void onAnimationCancel(Animator animation) { + // Do nothing. + } + + @Override + public void onAnimationRepeat(Animator animation) { + // Do nothing. + } + }; + + private LottieAnimationFinishListener(LottieAnimationView lottieAnimationView) { + this.lottieAnimationView = lottieAnimationView; + + if (lottieAnimationView != null && lottieAnimationView.isAnimating()) { + lottieAnimationView.addAnimatorListener(animatorListener); + lottieAnimationView.setRepeatCount(0); + } else { + onAnimationFinished(); + } + } + + public void removeListener() { + if (lottieAnimationView != null) { + lottieAnimationView.removeAnimatorListener(animatorListener); + } + animationFinishListener = null; + } + + abstract void onAnimationFinished(); + } + + @Retention(RetentionPolicy.SOURCE) + @StringDef({ + IllustrationType.ACCOUNT, + IllustrationType.CONNECTION, + IllustrationType.DEFAULT, + IllustrationType.UPDATE + }) + public @interface IllustrationType { + String DEFAULT = "default"; + String ACCOUNT = "account"; + String CONNECTION = "connection"; + String UPDATE = "update"; + } +} 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 c8e49d6..69965a0 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 @@ -28,6 +28,7 @@ android:orientation="horizontal"> <LinearLayout + android:id="@+id/suc_landscape_header_area" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" 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 8352a2d..3fb76b8 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 @@ -28,6 +28,7 @@ android:orientation="horizontal"> <LinearLayout + android:id="@+id/suc_landscape_header_area" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" 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 9f41222..2a60352 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 @@ -28,6 +28,7 @@ android:orientation="horizontal"> <LinearLayout + android:id="@+id/suc_landscape_header_area" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" 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 d89d693..7b46bc7 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 @@ -29,6 +29,7 @@ android:orientation="horizontal"> <LinearLayout + android:id="@+id/suc_landscape_header_area" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" 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 0fab9ca..8d24b6a 100644 --- a/main/res/layout-land-v31/sud_glif_template_content.xml +++ b/main/res/layout-land-v31/sud_glif_template_content.xml @@ -28,6 +28,7 @@ android:orientation="horizontal"> <LinearLayout + android:id="@+id/suc_landscape_header_area" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" diff --git a/main/res/values-land/dimens.xml b/main/res/values-land/dimens.xml index 88a97be..1867d3b 100644 --- a/main/res/values-land/dimens.xml +++ b/main/res/values-land/dimens.xml @@ -17,6 +17,11 @@ <resources> + <!-- General --> + <dimen name="sud_glif_button_min_height">36dp</dimen> + <dimen name="sud_glif_footer_min_height">52dp</dimen> + <dimen name="sud_glif_footer_padding_vertical">0dp</dimen> + <!-- Card layout (for tablets) --> <dimen name="sud_card_title_padding_end">32dp</dimen> <dimen name="sud_card_title_padding_start">56dp</dimen> diff --git a/main/res/values/attrs.xml b/main/res/values/attrs.xml index 63125ee..bd2902c 100644 --- a/main/res/values/attrs.xml +++ b/main/res/values/attrs.xml @@ -152,6 +152,10 @@ <attr name="android:width" /> </declare-styleable> + <attr name="sudContentIllustrationMaxWidth" format="dimension" /> + <attr name="sudContentIllustrationMaxHeight" format="dimension" /> + <attr name="sudContentIllustrationPaddingTop" format="dimension" /> + <attr name="sudContentIllustrationPaddingBottom" format="dimension" /> <declare-styleable name="SudFillContentLayout"> <attr name="android:maxHeight" /> <attr name="android:maxWidth" /> diff --git a/main/res/values/dimens.xml b/main/res/values/dimens.xml index aa2c16c..57b37c0 100644 --- a/main/res/values/dimens.xml +++ b/main/res/values/dimens.xml @@ -26,6 +26,7 @@ <!-- Calculated by (sud_glif_margin_start - sud_glif_button_padding) --> <dimen name="sud_glif_button_margin_start">8dp</dimen> <dimen name="sud_glif_button_padding">16dp</dimen> + <dimen name="sud_glif_button_min_height">48dp</dimen> <!-- Negative of sud_glif_button_padding --> <dimen name="sud_glif_negative_button_padding">-16dp</dimen> <dimen name="sud_glif_footer_padding_vertical">8dp</dimen> diff --git a/main/res/values/styles.xml b/main/res/values/styles.xml index 17e31d2..70a81a8 100644 --- a/main/res/values/styles.xml +++ b/main/res/values/styles.xml @@ -55,6 +55,10 @@ <item name="sudMarginEnd">@dimen/sud_layout_margin_sides</item> <item name="sudNavBarTheme">@style/SudNavBarThemeDark</item> <item name="textAppearanceListItemSmall">@style/TextAppearance.SudItemSummary</item> + <item name="sudContentIllustrationMaxWidth">@dimen/sud_content_illustration_max_width</item> + <item name="sudContentIllustrationMaxHeight">@dimen/sud_content_illustration_max_height</item> + <item name="sudContentIllustrationPaddingTop">@dimen/sud_content_illustration_padding_vertical</item> + <item name="sudContentIllustrationPaddingBottom">@dimen/sud_content_illustration_padding_vertical</item> </style> <style name="SudThemeMaterial.Light" parent="Theme.AppCompat.Light.NoActionBar"> @@ -93,6 +97,10 @@ <item name="sudMarginEnd">@dimen/sud_layout_margin_sides</item> <item name="sudNavBarTheme">@style/SudNavBarThemeLight</item> <item name="textAppearanceListItemSmall">@style/TextAppearance.SudItemSummary</item> + <item name="sudContentIllustrationMaxWidth">@dimen/sud_content_illustration_max_width</item> + <item name="sudContentIllustrationMaxHeight">@dimen/sud_content_illustration_max_height</item> + <item name="sudContentIllustrationPaddingTop">@dimen/sud_content_illustration_padding_vertical</item> + <item name="sudContentIllustrationPaddingBottom">@dimen/sud_content_illustration_padding_vertical</item> </style> <style name="SudBaseThemeGlif" parent="Theme.AppCompat.NoActionBar"> @@ -160,6 +168,10 @@ <item name="sucFooterBarMinHeight">@dimen/sud_glif_footer_min_height</item> <item name="sucFooterButtonPaddingStart">@dimen/sud_glif_button_padding</item> <item name="sucFooterButtonPaddingEnd">@dimen/sud_glif_button_padding</item> + <item name="sudContentIllustrationMaxWidth">@dimen/sud_content_illustration_max_width</item> + <item name="sudContentIllustrationMaxHeight">@dimen/sud_content_illustration_max_height</item> + <item name="sudContentIllustrationPaddingTop">@dimen/sud_content_illustration_padding_vertical</item> + <item name="sudContentIllustrationPaddingBottom">@dimen/sud_content_illustration_padding_vertical</item> </style> <style name="SudThemeGlif" parent="SudBaseThemeGlif"/> @@ -228,6 +240,10 @@ <item name="sucFooterBarMinHeight">@dimen/sud_glif_footer_min_height</item> <item name="sucFooterButtonPaddingStart">@dimen/sud_glif_button_padding</item> <item name="sucFooterButtonPaddingEnd">@dimen/sud_glif_button_padding</item> + <item name="sudContentIllustrationMaxWidth">@dimen/sud_content_illustration_max_width</item> + <item name="sudContentIllustrationMaxHeight">@dimen/sud_content_illustration_max_height</item> + <item name="sudContentIllustrationPaddingTop">@dimen/sud_content_illustration_padding_vertical</item> + <item name="sudContentIllustrationPaddingBottom">@dimen/sud_content_illustration_padding_vertical</item> </style> <style name="SudThemeGlif.Light" parent="SudBaseThemeGlif.Light"/> @@ -385,10 +401,10 @@ <style name="SudFillContentLayout"> <item name="android:minWidth">@dimen/sud_content_illustration_min_width</item> <item name="android:minHeight">@dimen/sud_content_illustration_min_height</item> - <item name="android:maxWidth">@dimen/sud_content_illustration_max_width</item> - <item name="android:maxHeight">@dimen/sud_content_illustration_max_height</item> - <item name="android:paddingTop">@dimen/sud_content_illustration_padding_vertical</item> - <item name="android:paddingBottom">@dimen/sud_content_illustration_padding_vertical</item> + <item name="android:maxWidth">?attr/sudContentIllustrationMaxWidth</item> + <item name="android:maxHeight">?attr/sudContentIllustrationMaxHeight</item> + <item name="android:paddingTop">?attr/sudContentIllustrationPaddingTop</item> + <item name="android:paddingBottom">?attr/sudContentIllustrationPaddingBottom</item> </style> <!-- Ignore UnusedResources: used by clients --> diff --git a/main/src/com/google/android/setupdesign/GlifLayout.java b/main/src/com/google/android/setupdesign/GlifLayout.java index ac778b4..b7d19ac 100644 --- a/main/src/com/google/android/setupdesign/GlifLayout.java +++ b/main/src/com/google/android/setupdesign/GlifLayout.java @@ -22,6 +22,7 @@ import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Build.VERSION_CODES; import android.util.AttributeSet; import android.view.LayoutInflater; @@ -35,6 +36,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import com.google.android.setupcompat.PartnerCustomizationLayout; import com.google.android.setupcompat.partnerconfig.PartnerConfig; import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; @@ -245,14 +247,27 @@ public class GlifLayout extends PartnerCustomizationLayout { return getMixin(DescriptionMixin.class).getTextView(); } - public void setDescriptionText(int title) { + /** + * Sets the description text and also sets the text visibility to visible. This can also be set + * via the XML attribute {@code app:sudDescriptionText}. + * + * @param title The resource ID of the text to be set as description + */ + public void setDescriptionText(@StringRes int title) { getMixin(DescriptionMixin.class).setText(title); } + /** + * Sets the description text and also sets the text visibility to visible. This can also be set + * via the XML attribute {@code app:sudDescriptionText}. + * + * @param title The text to be set as description + */ public void setDescriptionText(CharSequence title) { getMixin(DescriptionMixin.class).setText(title); } + /** Returns the current description text. */ public CharSequence getDescriptionText() { return getMixin(DescriptionMixin.class).getText(); } @@ -274,6 +289,23 @@ public class GlifLayout extends PartnerCustomizationLayout { } /** + * Sets the visibility of header area in landscape mode. These views inlcudes icon, header title + * and subtitle. It can make the content view become full screen when set false. + */ + @TargetApi(Build.VERSION_CODES.S) + public void setLandscapeHeaderAreaVisible(boolean visible) { + View view = this.findManagedViewById(R.id.suc_landscape_header_area); + if (view == null) { + return; + } + if (visible) { + view.setVisibility(View.VISIBLE); + } else { + view.setVisibility(View.GONE); + } + } + + /** * Sets the primary color of this layout, which will be used to determine the color of the * progress bar and the background pattern. */ diff --git a/main/src/com/google/android/setupdesign/template/DescriptionMixin.java b/main/src/com/google/android/setupdesign/template/DescriptionMixin.java index 983274f..bbccf82 100644 --- a/main/src/com/google/android/setupdesign/template/DescriptionMixin.java +++ b/main/src/com/google/android/setupdesign/template/DescriptionMixin.java @@ -20,12 +20,14 @@ import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; 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; @@ -39,6 +41,7 @@ import com.google.android.setupdesign.util.PartnerStyleHelper; */ public class DescriptionMixin implements Mixin { + private static final String TAG = "DescriptionMixin"; private final TemplateLayout templateLayout; /** @@ -100,22 +103,24 @@ public class DescriptionMixin implements Mixin { } /** - * Sets the description text and also sets the text visibility to visble. This can also be set via - * the XML attribute {@code app:sudDescriptionText}. + * Sets the description text and also sets the text visibility to visible. This can also be set + * via the XML attribute {@code app:sudDescriptionText}. * * @param title The resource ID of the text to be set as description */ - public void setText(int title) { + public void setText(@StringRes int title) { final TextView titleView = getTextView(); - if (titleView != null) { + if (titleView != null && title != 0) { titleView.setText(title); setVisibility(View.VISIBLE); + } else { + Log.w(TAG, "Fail to set text due to either invalid resource id or text view not found."); } } /** - * Sets the description text and also sets the text visibility to visble. This can also be set via - * the XML attribute {@code app:sudDescriptionText}. + * Sets the description text and also sets the text visibility to visible. This can also be set + * via the XML attribute {@code app:sudDescriptionText}. * * @param title The text to be set as description */ diff --git a/main/src/com/google/android/setupdesign/util/ThemeHelper.java b/main/src/com/google/android/setupdesign/util/ThemeHelper.java index c45b64f..7f29c5d 100644 --- a/main/src/com/google/android/setupdesign/util/ThemeHelper.java +++ b/main/src/com/google/android/setupdesign/util/ThemeHelper.java @@ -63,14 +63,12 @@ public final class ThemeHelper { public static final String THEME_GLIF_V3_LIGHT = "glif_v3_light"; /** - * Passed in a setup wizard intent as {@link WizardManagerHelper#EXTRA_THEME}. This is the dark - * variant of the theme used in setup wizard for S. + * Placeholder, not avirailed yet. */ public static final String THEME_GLIF_V4 = "glif_v4"; /** - * Passed in a setup wizard intent as {@link WizardManagerHelper#EXTRA_THEME}. This is the default - * theme used in setup wizard for S. + * Placeholder, not avirailed yet. */ public static final String THEME_GLIF_V4_LIGHT = "glif_v4_light"; diff --git a/main/src/com/google/android/setupdesign/util/ThemeResolver.java b/main/src/com/google/android/setupdesign/util/ThemeResolver.java index e6d3967..c7a28b1 100644 --- a/main/src/com/google/android/setupdesign/util/ThemeResolver.java +++ b/main/src/com/google/android/setupdesign/util/ThemeResolver.java @@ -139,7 +139,11 @@ public class ThemeResolver { /** Reads the theme from the intent, and applies the resolved theme to the activity. */ public void applyTheme(Activity activity) { - activity.setTheme(resolve(activity.getIntent())); + activity.setTheme( + resolve( + activity.getIntent(), + /* suppressDayNight= */ WizardManagerHelper.isAnySetupWizard(activity.getIntent()) + && !ThemeHelper.isSetupWizardDayNightEnabled(activity))); } /** |