Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 350b462f authored by Schneider Victor-tulias's avatar Schneider Victor-tulias
Browse files

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
parent a8e2ad2c
Loading
Loading
Loading
Loading
+44 −4
Original line number Diff line number Diff line
@@ -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();
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -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();
    }