Stop ProgressBar animations when not visible
Propagate setVisible calls to current drawable. Take window visibility
into account when determining drawable visibility.
Bug 27461595
Change-Id: Ia1de1d1686f26c2cf27630c5bde70f23c2c332bd
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 2099b04..72a50ec 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -17,21 +17,15 @@
package android.widget;
import android.animation.ObjectAnimator;
+import android.annotation.InterpolatorRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.graphics.PorterDuff;
-
-import android.util.FloatProperty;
-import android.util.IntProperty;
-import android.view.accessibility.AccessibilityNodeInfo;
-import com.android.internal.R;
-
-import android.annotation.InterpolatorRes;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.Animatable;
@@ -46,6 +40,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
+import android.util.FloatProperty;
import android.util.MathUtils;
import android.util.Pools.SynchronizedPool;
import android.view.Gravity;
@@ -55,6 +50,7 @@
import android.view.ViewHierarchyEncoder;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -63,6 +59,7 @@
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;
import android.widget.RemoteViews.RemoteView;
+import com.android.internal.R;
import java.util.ArrayList;
@@ -606,15 +603,30 @@
if (indeterminate) {
// swap between indeterminate and regular backgrounds
- mCurrentDrawable = mIndeterminateDrawable;
+ swapCurrentDrawable(mIndeterminateDrawable);
startAnimation();
} else {
- mCurrentDrawable = mProgressDrawable;
+ swapCurrentDrawable(mProgressDrawable);
stopAnimation();
}
}
}
+ private void swapCurrentDrawable(Drawable newDrawable) {
+ final Drawable oldDrawable = mCurrentDrawable;
+ mCurrentDrawable = newDrawable;
+ if (oldDrawable != mCurrentDrawable) {
+ if (oldDrawable != null) {
+ oldDrawable.setVisible(false, false);
+ }
+ if (mCurrentDrawable != null) {
+ mCurrentDrawable.setVisible(
+ getVisibility() == VISIBLE && getWindowVisibility() == VISIBLE,
+ false);
+ }
+ }
+ }
+
/**
* <p>Get the drawable used to draw the progress bar in
* indeterminate mode.</p>
@@ -654,7 +666,7 @@
}
if (mIndeterminate) {
- mCurrentDrawable = d;
+ swapCurrentDrawable(d);
postInvalidate();
}
}
@@ -820,7 +832,7 @@
}
if (!mIndeterminate) {
- mCurrentDrawable = d;
+ swapCurrentDrawable(d);
postInvalidate();
}
@@ -1555,7 +1567,7 @@
* <p>Start the indeterminate progress animation.</p>
*/
void startAnimation() {
- if (getVisibility() != VISIBLE) {
+ if (getVisibility() != VISIBLE || getWindowVisibility() != VISIBLE) {
return;
}
@@ -1653,14 +1665,30 @@
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
+ updateVisibility();
+ }
+
+ @Override
+ protected void onWindowVisibilityChanged(@Visibility int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+
+ updateVisibility();
+ }
+
+ private void updateVisibility() {
+ final boolean isVisible = getVisibility() == VISIBLE && getWindowVisibility() == VISIBLE;
if (mIndeterminate) {
// let's be nice with the UI thread
- if (visibility == GONE || visibility == INVISIBLE) {
- stopAnimation();
- } else {
+ if (isVisible) {
startAnimation();
+ } else {
+ stopAnimation();
}
}
+
+ if (mCurrentDrawable != null) {
+ mCurrentDrawable.setVisible(isVisible, false);
+ }
}
@Override