Do not animate QS state changes when not in view.
Skip QS state change animations when the target view is not fully visible on screen. Some tiles require extra time before the status is fully changed and therefore will be animated later. Change-Id: I08e76e0fdeab2b260cb7a41a117a6ff484ca3329 Fixes: 111680760 Test: visual and runtest systemui
This commit is contained in:
committed by
Fabian Kozynski
parent
50f913614a
commit
32d786fb73
@@ -29,7 +29,7 @@ public abstract class QSIconView extends ViewGroup {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public abstract void setIcon(State state);
|
||||
public abstract void setIcon(State state, boolean allowAnimations);
|
||||
public abstract void disableAnimation();
|
||||
public abstract View getIconView();
|
||||
}
|
||||
|
||||
@@ -43,9 +43,9 @@ public class CellTileView extends SignalTileView {
|
||||
R.dimen.qs_tile_icon_size));
|
||||
}
|
||||
|
||||
protected void updateIcon(ImageView iv, State state) {
|
||||
protected void updateIcon(ImageView iv, State state, boolean allowAnimations) {
|
||||
if (!(state.icon instanceof SignalIcon)) {
|
||||
super.updateIcon(iv, state);
|
||||
super.updateIcon(iv, state, allowAnimations);
|
||||
return;
|
||||
} else if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
|
||||
mSignalDrawable.setLevel(((SignalIcon) state.icon).getState());
|
||||
|
||||
@@ -18,14 +18,13 @@ package com.android.systemui.qs;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.qs.QSTile;
|
||||
import com.android.systemui.plugins.qs.QSTile.SignalState;
|
||||
import com.android.systemui.plugins.qs.QSTile.State;
|
||||
import com.android.systemui.qs.tileimpl.QSIconViewImpl;
|
||||
import com.android.systemui.qs.tileimpl.SlashImageView;
|
||||
|
||||
@@ -119,9 +118,9 @@ public class SignalTileView extends QSIconViewImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(QSTile.State state) {
|
||||
public void setIcon(State state, boolean allowAnimations) {
|
||||
final SignalState s = (SignalState) state;
|
||||
setIcon(mSignal, s);
|
||||
setIcon(mSignal, s, allowAnimations);
|
||||
|
||||
if (s.overlayIconId > 0) {
|
||||
mOverlay.setVisibility(VISIBLE);
|
||||
@@ -134,9 +133,9 @@ public class SignalTileView extends QSIconViewImpl {
|
||||
} else {
|
||||
mSignal.setPaddingRelative(0, 0, 0, 0);
|
||||
}
|
||||
final boolean shown = isShown();
|
||||
setVisibility(mIn, shown, s.activityIn);
|
||||
setVisibility(mOut, shown, s.activityOut);
|
||||
final boolean shouldAnimate = allowAnimations && isShown();
|
||||
setVisibility(mIn, shouldAnimate, s.activityIn);
|
||||
setVisibility(mOut, shouldAnimate, s.activityOut);
|
||||
}
|
||||
|
||||
private void setVisibility(View view, boolean shown, boolean visible) {
|
||||
|
||||
@@ -84,16 +84,15 @@ public class QSIconViewImpl extends QSIconView {
|
||||
layout(mIcon, iconLeft, top);
|
||||
}
|
||||
|
||||
public void setIcon(QSTile.State state) {
|
||||
setIcon((ImageView) mIcon, state);
|
||||
public void setIcon(State state, boolean allowAnimations) {
|
||||
setIcon((ImageView) mIcon, state, allowAnimations);
|
||||
}
|
||||
|
||||
protected void updateIcon(ImageView iv, State state) {
|
||||
protected void updateIcon(ImageView iv, State state, boolean allowAnimations) {
|
||||
final QSTile.Icon icon = state.iconSupplier != null ? state.iconSupplier.get() : state.icon;
|
||||
if (!Objects.equals(icon, iv.getTag(R.id.qs_icon_tag))
|
||||
|| !Objects.equals(state.slash, iv.getTag(R.id.qs_slash_tag))) {
|
||||
boolean shouldAnimate = iv.isShown() && mAnimationEnabled
|
||||
&& iv.getDrawable() != null;
|
||||
boolean shouldAnimate = allowAnimations && shouldAnimate(iv);
|
||||
Drawable d = icon != null
|
||||
? shouldAnimate ? icon.getDrawable(mContext)
|
||||
: icon.getInvisibleDrawable(mContext) : null;
|
||||
@@ -128,7 +127,11 @@ public class QSIconViewImpl extends QSIconView {
|
||||
}
|
||||
}
|
||||
|
||||
protected void setIcon(ImageView iv, QSTile.State state) {
|
||||
private boolean shouldAnimate(ImageView iv) {
|
||||
return mAnimationEnabled && iv.isShown() && iv.getDrawable() != null;
|
||||
}
|
||||
|
||||
protected void setIcon(ImageView iv, QSTile.State state, boolean allowAnimations) {
|
||||
if (state.disabledByPolicy) {
|
||||
iv.setColorFilter(getContext().getColor(R.color.qs_tile_disabled_color));
|
||||
} else {
|
||||
@@ -137,8 +140,8 @@ public class QSIconViewImpl extends QSIconView {
|
||||
if (state.state != mState) {
|
||||
int color = getColor(state.state);
|
||||
mState = state.state;
|
||||
if (iv.isShown() && mTint != 0) {
|
||||
animateGrayScale(mTint, color, iv, () -> updateIcon(iv, state));
|
||||
if (mTint != 0 && allowAnimations && shouldAnimate(iv)) {
|
||||
animateGrayScale(mTint, color, iv, () -> updateIcon(iv, state, allowAnimations));
|
||||
mTint = color;
|
||||
} else {
|
||||
if (iv instanceof AlphaControlledSlashImageView) {
|
||||
@@ -148,10 +151,10 @@ public class QSIconViewImpl extends QSIconView {
|
||||
setTint(iv, color);
|
||||
}
|
||||
mTint = color;
|
||||
updateIcon(iv, state);
|
||||
updateIcon(iv, state, allowAnimations);
|
||||
}
|
||||
} else {
|
||||
updateIcon(iv, state);
|
||||
updateIcon(iv, state, allowAnimations);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
|
||||
|
||||
private static final String TAG = "QSTileBaseView";
|
||||
private final H mHandler = new H();
|
||||
private final int[] mLocInScreen = new int[2];
|
||||
private final FrameLayout mIconFrame;
|
||||
protected QSIconView mIcon;
|
||||
protected RippleDrawable mRipple;
|
||||
@@ -178,8 +179,9 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
|
||||
|
||||
protected void handleStateChanged(QSTile.State state) {
|
||||
int circleColor = getCircleColor(state.state);
|
||||
boolean allowAnimations = animationsEnabled();
|
||||
if (circleColor != mCircleColor) {
|
||||
if (mBg.isShown() && animationsEnabled()) {
|
||||
if (allowAnimations) {
|
||||
ValueAnimator animator = ValueAnimator.ofArgb(mCircleColor, circleColor)
|
||||
.setDuration(QS_ANIM_LENGTH);
|
||||
animator.addUpdateListener(animation -> mBg.setImageTintList(ColorStateList.valueOf(
|
||||
@@ -192,7 +194,7 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
|
||||
}
|
||||
|
||||
setClickable(state.state != Tile.STATE_UNAVAILABLE);
|
||||
mIcon.setIcon(state);
|
||||
mIcon.setIcon(state, allowAnimations);
|
||||
setContentDescription(state.contentDescription);
|
||||
|
||||
mAccessibilityClass = state.expandedAccessibilityClassName;
|
||||
@@ -205,8 +207,17 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
|
||||
}
|
||||
}
|
||||
|
||||
/* The view should not be animated if it's not on screen and no part of it is visible.
|
||||
*/
|
||||
protected boolean animationsEnabled() {
|
||||
return true;
|
||||
if (!isShown()) {
|
||||
return false;
|
||||
}
|
||||
if (getAlpha() != 1f) {
|
||||
return false;
|
||||
}
|
||||
getLocationOnScreen(mLocInScreen);
|
||||
return mLocInScreen[1] >= -getHeight();
|
||||
}
|
||||
|
||||
private int getCircleColor(int state) {
|
||||
|
||||
@@ -59,14 +59,14 @@ public class QSIconViewImplTest extends SysuiTestCase {
|
||||
// No current icon, only the static drawable should be used.
|
||||
s.icon = mock(Icon.class);
|
||||
when(iv.getDrawable()).thenReturn(null);
|
||||
mIconView.updateIcon(iv, s);
|
||||
mIconView.updateIcon(iv, s, true);
|
||||
verify(s.icon, never()).getDrawable(any());
|
||||
verify(s.icon).getInvisibleDrawable(any());
|
||||
|
||||
// Has icon, should use the standard (animated) form.
|
||||
s.icon = mock(Icon.class);
|
||||
when(iv.getDrawable()).thenReturn(mock(Drawable.class));
|
||||
mIconView.updateIcon(iv, s);
|
||||
mIconView.updateIcon(iv, s, true);
|
||||
verify(s.icon).getDrawable(any());
|
||||
verify(s.icon, never()).getInvisibleDrawable(any());
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public class QSIconViewImplTest extends SysuiTestCase {
|
||||
int desiredColor = mIconView.getColor(s.state);
|
||||
when(iv.isShown()).thenReturn(true);
|
||||
|
||||
mIconView.setIcon(iv, s);
|
||||
mIconView.setIcon(iv, s, true);
|
||||
verify(iv).setImageTintList(argThat(stateList -> stateList.getColors()[0] == desiredColor));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user