summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tyler Dewey <deweytyl@google.com> 2025-01-03 09:51:23 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-01-03 09:51:23 -0800
commita1bcf843633357867625ba2eb69236fc544cd13f (patch)
treedd8bf0316b486f451fc092d6bd6001e5a87eb73c
parent33d746baf4b58e84e1c0986acb451c682a2ea85b (diff)
parentaf4c722b3f8ea843223874d84f0e1130b370f21d (diff)
Merge "Use TextSwitcher for animating status card text changes." into main
-rw-r--r--PermissionController/res/anim/text_switcher_fade_in.xml22
-rw-r--r--PermissionController/res/anim/text_switcher_fade_out.xml21
-rw-r--r--PermissionController/res/layout-v33/view_status_card.xml31
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java56
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt25
5 files changed, 93 insertions, 62 deletions
diff --git a/PermissionController/res/anim/text_switcher_fade_in.xml b/PermissionController/res/anim/text_switcher_fade_in.xml
new file mode 100644
index 000000000..b9e2812aa
--- /dev/null
+++ b/PermissionController/res/anim/text_switcher_fade_in.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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.
+ -->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:startOffset="@android:integer/config_shortAnimTime"
+ android:duration="@android:integer/config_shortAnimTime" /> \ No newline at end of file
diff --git a/PermissionController/res/anim/text_switcher_fade_out.xml b/PermissionController/res/anim/text_switcher_fade_out.xml
new file mode 100644
index 000000000..4b7274707
--- /dev/null
+++ b/PermissionController/res/anim/text_switcher_fade_out.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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.
+ -->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="@android:integer/config_shortAnimTime" /> \ No newline at end of file
diff --git a/PermissionController/res/layout-v33/view_status_card.xml b/PermissionController/res/layout-v33/view_status_card.xml
index 4915347be..d8ca8b7ea 100644
--- a/PermissionController/res/layout-v33/view_status_card.xml
+++ b/PermissionController/res/layout-v33/view_status_card.xml
@@ -30,15 +30,34 @@
android:id="@+id/status_title_and_summary"
style="?attr/scStatusTitleAndSummaryContainerStyle">
- <TextView
+ <TextSwitcher
android:id="@+id/status_title"
- android:text="@string/summary_placeholder"
- style="@style/SafetyCenterStatusTitle" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:inAnimation="@anim/text_switcher_fade_in"
+ android:outAnimation="@anim/text_switcher_fade_out">
+ <TextView
+ android:text="@string/summary_placeholder"
+ style="@style/SafetyCenterStatusTitle" />
+ <TextView
+ android:text="@string/summary_placeholder"
+ style="@style/SafetyCenterStatusTitle" />
+ </TextSwitcher>
- <TextView
+
+ <TextSwitcher
android:id="@+id/status_summary"
- android:text="@string/summary_placeholder"
- style="@style/SafetyCenterStatusSummary" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:inAnimation="@anim/text_switcher_fade_in"
+ android:outAnimation="@anim/text_switcher_fade_out">
+ <TextView
+ android:text="@string/summary_placeholder"
+ style="@style/SafetyCenterStatusSummary" />
+ <TextView
+ android:text="@string/summary_placeholder"
+ style="@style/SafetyCenterStatusSummary" />
+ </TextSwitcher>
</LinearLayout>
<androidx.constraintlayout.widget.Barrier
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java
index abf159955..0bef71b3e 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java
@@ -29,7 +29,6 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
-import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
@@ -42,9 +41,6 @@ import com.android.permissioncontroller.safetycenter.ui.model.StatusUiData;
import com.android.permissioncontroller.safetycenter.ui.view.StatusCardView;
import com.android.settingslib.widget.GroupSectionDividerMixin;
-import kotlin.Pair;
-
-import java.util.List;
import java.util.Objects;
/** Preference which displays a visual representation of {@link SafetyCenterStatus}. */
@@ -54,25 +50,16 @@ public class SafetyStatusPreference extends Preference
private static final String TAG = "SafetyStatusPreference";
+ private final SafetyStatusAnimationSequencer mSequencer = new SafetyStatusAnimationSequencer();
+
@Nullable private StatusUiData mStatus;
@Nullable private SafetyCenterViewModel mViewModel;
- private final TextFadeAnimator mTitleTextAnimator = new TextFadeAnimator(R.id.status_title);
-
- private final TextFadeAnimator mSummaryTextAnimator = new TextFadeAnimator(R.id.status_summary);
-
- private final TextFadeAnimator mAllTextAnimator =
- new TextFadeAnimator(List.of(R.id.status_title, R.id.status_summary));
-
- private boolean mFirstBind = true;
-
public SafetyStatusPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.preference_safety_status);
}
- private boolean mIsTextChangeAnimationRunning;
- private final SafetyStatusAnimationSequencer mSequencer = new SafetyStatusAnimationSequencer();
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
@@ -93,9 +80,7 @@ public class SafetyStatusPreference extends Preference
updateStatusIcon(statusCardView);
- updateStatusText(statusCardView.getTitleView(), statusCardView.getSummaryView());
-
- mFirstBind = false;
+ statusCardView.showText(mStatus);
}
private void configureButtons(Context context, StatusCardView statusCardView) {
@@ -125,14 +110,6 @@ public class SafetyStatusPreference extends Preference
statusCardView.showButtons(mStatus);
}
- private void updateStatusText(TextView title, TextView summary) {
- if (mFirstBind) {
- title.setText(mStatus.getTitle());
- summary.setText(mStatus.getSummary(getContext()));
- }
- runTextAnimationIfNeeded(title, summary);
- }
-
private void updateStatusIcon(StatusCardView statusCardView) {
int severityLevel = mStatus.getSeverityLevel();
boolean isRefreshing = mStatus.isRefreshInProgress();
@@ -143,33 +120,6 @@ public class SafetyStatusPreference extends Preference
/* scanningAnimation= */ null);
}
- private void runTextAnimationIfNeeded(TextView titleView, TextView summaryView) {
- if (mIsTextChangeAnimationRunning) {
- return;
- }
- Log.v(TAG, "Starting status text animation");
- String titleText = mStatus.getTitle().toString();
- String summaryText = mStatus.getSummary(getContext()).toString();
- boolean titleEquals = titleView.getText().toString().equals(titleText);
- boolean summaryEquals = summaryView.getText().toString().equals(summaryText);
- Runnable onFinish =
- () -> {
- Log.v(TAG, "Finishing status text animation");
- mIsTextChangeAnimationRunning = false;
- runTextAnimationIfNeeded(titleView, summaryView);
- };
- mIsTextChangeAnimationRunning = !titleEquals || !summaryEquals;
- if (!titleEquals && !summaryEquals) {
- Pair<TextView, String> titleChange = new Pair<>(titleView, titleText);
- Pair<TextView, String> summaryChange = new Pair<>(summaryView, summaryText);
- mAllTextAnimator.animateChangeText(List.of(titleChange, summaryChange), onFinish);
- } else if (!titleEquals) {
- mTitleTextAnimator.animateChangeText(titleView, titleText, onFinish);
- } else if (!summaryEquals) {
- mSummaryTextAnimator.animateChangeText(summaryView, summaryText, onFinish);
- }
- }
-
private void startScanningAnimation(StatusCardView statusCardView) {
mSequencer.onStartScanningAnimationStart();
ImageView statusImage = statusCardView.getStatusImageView();
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt
index 6a415c563..bb417104d 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt
@@ -21,6 +21,7 @@ import android.os.Build
import android.util.AttributeSet
import android.widget.ImageView
import android.widget.LinearLayout
+import android.widget.TextSwitcher
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.constraintlayout.widget.ConstraintLayout
@@ -35,7 +36,7 @@ constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
- defStyleRes: Int = 0
+ defStyleRes: Int = 0,
) : ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {
init {
@@ -44,11 +45,29 @@ constructor(
val statusImageView: ImageView by lazyView(R.id.status_image)
val titleAndSummaryContainerView: LinearLayout by lazyView(R.id.status_title_and_summary)
- val titleView: TextView by lazyView(R.id.status_title)
- val summaryView: TextView by lazyView(R.id.status_summary)
+ private val titleView: TextSwitcher by lazyView(R.id.status_title)
+ private val summaryView: TextSwitcher by lazyView(R.id.status_summary)
val reviewSettingsButton: MaterialButton by lazyView(R.id.review_settings_button)
val rescanButton: MaterialButton by lazyView(R.id.rescan_button)
+ fun showText(statusUiData: StatusUiData) {
+ titleView.updateText(statusUiData.title)
+ summaryView.updateText(statusUiData.getSummary(context))
+ }
+
+ private fun TextSwitcher.updateText(newText: CharSequence) {
+ val currentText: CharSequence? = (currentView as TextView).text
+ if (currentText == newText) {
+ return
+ }
+
+ if (currentText.isNullOrBlank()) {
+ setCurrentText(newText)
+ } else {
+ setText(newText)
+ }
+ }
+
fun showButtons(statusUiData: StatusUiData) {
rescanButton.isEnabled = !statusUiData.isRefreshInProgress