Animate icon update from loading state.

Test: manual

Fixing b/129983531. Having app icons pop in without any animation from a solid placeholder color can look janky. Added a sequential fade in, fade out animation.

Preview: https://drive.google.com/file/d/11NgEja7vzm3f3aH3WbEQljUWGKuuK00_/view?usp=sharing
Change-Id: If77e8f480b02d5b7d29f89afa44450c83a68a276
This commit is contained in:
Schneider Victor-tulias 2020-09-18 11:16:30 -07:00
parent a8e2ad2c1f
commit 350b462f24
2 changed files with 51 additions and 6 deletions

View File

@ -23,6 +23,7 @@ import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
@ -30,6 +31,8 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@ -43,6 +46,8 @@ import android.view.View;
import android.view.ViewDebug;
import android.widget.TextView;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.Launcher.OnResumeCallback;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.dot.DotInfo;
@ -50,6 +55,7 @@ import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.graphics.PlaceHolderIconDrawable;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.IconCache.IconLoadRequest;
@ -84,6 +90,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private final PointF mTranslationForReorderBounce = new PointF(0, 0);
private final PointF mTranslationForReorderPreview = new PointF(0, 0);
private static final int ICON_UPDATE_ANIMATION_DURATION = 375;
private float mScaleForReorderBounce = 1f;
private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
@ -636,11 +644,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
mDisableRelayout = mIcon != null;
icon.setBounds(0, 0, mIconSize, mIconSize);
if (mLayoutHorizontal) {
setCompoundDrawablesRelative(icon, null, null, null);
} else {
setCompoundDrawables(null, icon, null, null);
updateIcon(icon);
// If the current icon is a placeholder color, animate its update.
if (mIcon != null && mIcon instanceof PlaceHolderIconDrawable) {
animateIconUpdate((PlaceHolderIconDrawable) mIcon, icon);
}
mDisableRelayout = false;
}
@ -776,4 +787,33 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
((FastBitmapDrawable) mIcon).setScale(1f);
}
}
private void updateIcon(Drawable newIcon) {
if (mLayoutHorizontal) {
setCompoundDrawablesRelative(newIcon, null, null, null);
} else {
setCompoundDrawables(null, newIcon, null, null);
}
}
private static void animateIconUpdate(PlaceHolderIconDrawable oldIcon, Drawable newIcon) {
int placeholderColor = oldIcon.mPaint.getColor();
int originalAlpha = Color.alpha(placeholderColor);
ValueAnimator iconUpdateAnimation = ValueAnimator.ofInt(originalAlpha, 0);
iconUpdateAnimation.setDuration(ICON_UPDATE_ANIMATION_DURATION);
iconUpdateAnimation.addUpdateListener(valueAnimator -> {
int newAlpha = (int) valueAnimator.getAnimatedValue();
int newColor = ColorUtils.setAlphaComponent(placeholderColor, newAlpha);
newIcon.setColorFilter(new PorterDuffColorFilter(newColor, Mode.SRC_ATOP));
});
iconUpdateAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
newIcon.setColorFilter(null);
}
});
iconUpdateAnimation.start();
}
}

View File

@ -33,6 +33,8 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.Property;
import androidx.annotation.Nullable;
import com.android.launcher3.graphics.PlaceHolderIconDrawable;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
@ -54,6 +56,8 @@ public class FastBitmapDrawable extends Drawable {
protected Bitmap mBitmap;
protected final int mIconColor;
@Nullable private ColorFilter mColorFilter;
private boolean mIsPressed;
private boolean mIsDisabled;
private float mDisabledAlpha = 1f;
@ -115,7 +119,8 @@ public class FastBitmapDrawable extends Drawable {
@Override
public void setColorFilter(ColorFilter cf) {
// No op
mColorFilter = cf;
updateFilter();
}
@Override
@ -265,7 +270,7 @@ public class FastBitmapDrawable extends Drawable {
* Updates the paint to reflect the current brightness and saturation.
*/
protected void updateFilter() {
mPaint.setColorFilter(mIsDisabled ? getDisabledColorFilter() : null);
mPaint.setColorFilter(mIsDisabled ? getDisabledColorFilter() : mColorFilter);
invalidateSelf();
}