Merge "Add icon scale and alpha animation for entering downloading state from pending state" into tm-qpr-dev
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index 9a961ca..de47cb5 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -17,6 +17,7 @@
package com.android.launcher3.graphics;
+import static com.android.launcher3.anim.Interpolators.EMPHASIZED;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V2;
@@ -39,6 +40,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.model.data.ItemInfoWithIcon;
@@ -72,12 +74,13 @@
private static final int DISABLED_ICON_ALPHA = (int) (0.6f * MAX_PAINT_ALPHA);
private static final long DURATION_SCALE = 500;
+ private static final long SCALE_AND_ALPHA_ANIM_DURATION = 500;
// The smaller the number, the faster the animation would be.
// Duration = COMPLETE_ANIM_FRACTION * DURATION_SCALE
private static final float COMPLETE_ANIM_FRACTION = 0.3f;
- private static final float SMALL_SCALE = ENABLE_DOWNLOAD_APP_UX_V2.get() ? 0.85f : 0.7f;
+ private static final float SMALL_SCALE = ENABLE_DOWNLOAD_APP_UX_V2.get() ? 0.867f : 0.7f;
private static final float PROGRESS_STROKE_SCALE = 0.075f;
private static final int PRELOAD_ACCENT_COLOR_INDEX = 0;
@@ -110,12 +113,13 @@
private int mTrackAlpha;
private float mTrackLength;
- private float mIconScale;
private boolean mRanFinishAnimation;
- private int mOverlayAlpha = 127;
- private int mRefreshRateMillis;
+ private final int mRefreshRateMillis;
+ private final AnimatedFloat mIconScale = new AnimatedFloat(this::invalidateSelf);
+ private final AnimatedFloat mOverlayAlpha = new AnimatedFloat(this::updateOverlayAlpha);
+ private boolean mShouldAnimateScaleAndAlpha;
// Progress of the internal state. [0, 1] indicates the fraction of completed progress,
// [1, (1 + COMPLETE_ANIM_FRACTION)] indicates the progress of zoom animation.
@@ -155,6 +159,12 @@
mIsDarkMode = isDarkMode;
mRefreshRateMillis = refreshRateMillis;
+ // If it's a pending app we will animate scale and alpha when it's no longer pending.
+ if (ENABLE_DOWNLOAD_APP_UX_V2.get() && info.getProgressLevel() == 0) {
+ mShouldAnimateScaleAndAlpha = true;
+ mOverlayAlpha.updateValue(127);
+ }
+
setLevel(info.getProgressLevel());
setIsStartable(info.isAppStartable());
}
@@ -199,7 +209,8 @@
canvas.drawPath(mScaledProgressPath, mProgressPaint);
int saveCount = canvas.save();
- canvas.scale(mIconScale, mIconScale, bounds.exactCenterX(), bounds.exactCenterY());
+ canvas.scale(
+ mIconScale.value, mIconScale.value, bounds.exactCenterX(), bounds.exactCenterY());
super.drawInternal(canvas, bounds);
canvas.restoreToCount(saveCount);
@@ -301,18 +312,34 @@
* - only icon is drawn in normal state
*/
private void setInternalProgress(float progress) {
+ // Animate scale and alpha from pending to downloading state.
+ if (ENABLE_DOWNLOAD_APP_UX_V2.get()
+ && mShouldAnimateScaleAndAlpha && mInternalStateProgress == 0 && progress > 0) {
+ Animator iconScaleAnimator = mIconScale.animateToValue(SMALL_SCALE);
+ iconScaleAnimator.setDuration(SCALE_AND_ALPHA_ANIM_DURATION);
+ iconScaleAnimator.setInterpolator(EMPHASIZED);
+ iconScaleAnimator.start();
+
+ Animator overlayAlphaAnimator = mOverlayAlpha.animateToValue(0);
+ overlayAlphaAnimator.setDuration(SCALE_AND_ALPHA_ANIM_DURATION);
+ overlayAlphaAnimator.setInterpolator(EMPHASIZED);
+ overlayAlphaAnimator.start();
+ }
+
mInternalStateProgress = progress;
if (progress <= 0) {
- mIconScale = ENABLE_DOWNLOAD_APP_UX_V2.get() ? 1 : SMALL_SCALE;
+ mIconScale.updateValue(ENABLE_DOWNLOAD_APP_UX_V2.get() ? 1 : SMALL_SCALE);
mScaledTrackPath.reset();
mTrackAlpha = MAX_PAINT_ALPHA;
} else if (progress < 1) {
mPathMeasure.getSegment(0, progress * mTrackLength, mScaledProgressPath, true);
if (ENABLE_DOWNLOAD_APP_UX_V2.get()) {
- mPaint.setColorFilter(null);
mPathMeasure.getSegment(0, mTrackLength, mScaledTrackPath, true);
}
- mIconScale = SMALL_SCALE;
+
+ if (!ENABLE_DOWNLOAD_APP_UX_V2.get() || !mShouldAnimateScaleAndAlpha) {
+ mIconScale.updateValue(SMALL_SCALE);
+ }
mTrackAlpha = MAX_PAINT_ALPHA;
} else {
setIsDisabled(mItem.isDisabled());
@@ -321,11 +348,11 @@
if (fraction >= 1) {
// Animation has completed
- mIconScale = 1;
+ mIconScale.updateValue(1);
mTrackAlpha = 0;
} else {
mTrackAlpha = Math.round((1 - fraction) * MAX_PAINT_ALPHA);
- mIconScale = SMALL_SCALE + (1 - SMALL_SCALE) * fraction;
+ mIconScale.updateValue(SMALL_SCALE + (1 - SMALL_SCALE) * fraction);
}
}
invalidateSelf();
@@ -370,9 +397,7 @@
if (!ENABLE_DOWNLOAD_APP_UX_V2.get() || mInternalStateProgress > 0) {
return;
}
- if (applyPendingIconOverlay()) {
- invalidateSelf();
- } else {
+ if (!applyPendingIconOverlay()) {
reschedule();
}
}
@@ -408,7 +433,7 @@
long waveMotionDelay = (mItem.cellX * WAVE_MOTION_DELAY_FACTOR_MILLIS)
+ (mItem.cellY * WAVE_MOTION_DELAY_FACTOR_MILLIS);
long time = SystemClock.uptimeMillis();
- int newAlpha = (int) Utilities.mapBoundToRange(
+ float newAlpha = Utilities.mapBoundToRange(
(float) (time + waveMotionDelay) % ALPHA_DURATION_MILLIS,
0,
ALPHA_DURATION_MILLIS,
@@ -416,22 +441,25 @@
MAX_PAINT_ALPHA,
LINEAR);
if (newAlpha > OVERLAY_ALPHA_RANGE) {
- newAlpha = (int) (OVERLAY_ALPHA_RANGE - (newAlpha % OVERLAY_ALPHA_RANGE));
+ newAlpha = (OVERLAY_ALPHA_RANGE - (newAlpha % OVERLAY_ALPHA_RANGE));
}
boolean invalidate = false;
- if (mOverlayAlpha != newAlpha) {
- mOverlayAlpha = newAlpha;
- int overlayColor = mIsDarkMode ? 0 : 255;
- int currArgb = Color.argb(mOverlayAlpha, overlayColor, overlayColor, overlayColor);
- mPaint.setColorFilter(COLOR_FILTER_MAP.computeIfAbsent(
- currArgb,
- FILTER_FACTORY));
+ if ((int) mOverlayAlpha.value != newAlpha) {
+ mOverlayAlpha.updateValue(newAlpha);
invalidate = true;
}
return invalidate;
}
+ private void updateOverlayAlpha() {
+ int overlayColor = mIsDarkMode ? 0 : 255;
+ int currArgb =
+ Color.argb((int) mOverlayAlpha.value, overlayColor, overlayColor, overlayColor);
+ mPaint.setColorFilter(COLOR_FILTER_MAP.computeIfAbsent(currArgb, FILTER_FACTORY));
+ invalidateSelf();
+ }
+
protected static class PreloadIconConstantState extends FastBitmapConstantState {
protected final ItemInfoWithIcon mInfo;