diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 06bb263f23..fd04081198 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -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 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(); + } } diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java index d3b86ded80..139d4a85e4 100644 --- a/src/com/android/launcher3/FastBitmapDrawable.java +++ b/src/com/android/launcher3/FastBitmapDrawable.java @@ -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(); }