Fix shadow problems with Folder animation.
The shadow from the top of the Folder is visible through
the transparent part of the 'preview' background. When we
remove the elevation as part of the animation, the shadow
jumps into visibility when the animation is done.
To solve this, we remove the elevation during the Folder animation and
* Animate the elevation at the end of the Folder opening animation.
* Animate the shadow of the FolderIcon bg in once the Folder is closed.
Bug: 62787582
Bug: 35064148
Change-Id: Id5d8fcbfa4f74882531334f12488560da2496faf
diff --git a/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
index d01b26c..7c5fa1c 100644
--- a/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
+++ b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
@@ -56,7 +56,7 @@
@Override
public boolean shouldRemoveElevationDuringAnimation() {
- return false;
+ return true;
}
@Override
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index fc25c9a..2838351 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -791,8 +791,11 @@
mDragController.removeDropTarget(this);
clearFocus();
if (mFolderIcon != null) {
- mFolderIcon.setBackgroundVisible(true);
mFolderIcon.setVisibility(View.VISIBLE);
+ if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+ mFolderIcon.setBackgroundVisible(true);
+ mFolderIcon.mBackground.fadeInBackgroundShadow();
+ }
if (wasAnimated) {
mFolderIcon.mBackground.animateBackgroundStroke();
if (mFolderIcon.hasBadge()) {
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index bb2d1a2..74e8d3b 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -221,6 +221,12 @@
mFolder.setTranslationY(0.0f);
mFolder.setScaleX(1f);
mFolder.setScaleY(1f);
+
+ if (mIsOpening) {
+ getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0)
+ .setDuration(150)
+ .start();
+ }
}
});
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index aaa19af..ca5d308 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -555,6 +555,7 @@
private int mBgColor;
private float mStrokeWidth;
private int mStrokeAlpha = MAX_BG_OPACITY;
+ private int mShadowAlpha = 255;
private View mInvalidateDelegate;
public int previewSize;
@@ -580,6 +581,7 @@
ValueAnimator mScaleAnimator;
ObjectAnimator mStrokeAlphaAnimator;
+ ObjectAnimator mShadowAnimator;
private static final Property<PreviewBackground, Integer> STROKE_ALPHA =
new Property<PreviewBackground, Integer>(Integer.class, "strokeAlpha") {
@@ -595,6 +597,20 @@
}
};
+ private static final Property<PreviewBackground, Integer> SHADOW_ALPHA =
+ new Property<PreviewBackground, Integer>(Integer.class, "shadowAlpha") {
+ @Override
+ public Integer get(PreviewBackground previewBackground) {
+ return previewBackground.mShadowAlpha;
+ }
+
+ @Override
+ public void set(PreviewBackground previewBackground, Integer alpha) {
+ previewBackground.mShadowAlpha = alpha;
+ previewBackground.invalidate();
+ }
+ };
+
public void setup(Launcher launcher, View invalidateDelegate,
int availableSpace, int topPadding) {
mInvalidateDelegate = invalidateDelegate;
@@ -692,10 +708,11 @@
mShaderMatrix.setScale(shadowRadius, shadowRadius);
mShaderMatrix.postTranslate(radius + offsetX, shadowRadius + offsetY);
mShadowShader.setLocalMatrix(mShaderMatrix);
+ mPaint.setAlpha(mShadowAlpha);
mPaint.setShader(mShadowShader);
canvas.drawPaint(mPaint);
+ mPaint.setAlpha(255);
mPaint.setShader(null);
-
if (canvas.isHardwareAccelerated()) {
mPaint.setXfermode(mShadowPorterDuffXfermode);
canvas.drawCircle(radius + offsetX, radius + offsetY, radius, mPaint);
@@ -705,6 +722,22 @@
canvas.restoreToCount(saveCount);
}
+ public void fadeInBackgroundShadow() {
+ if (mShadowAnimator != null) {
+ mShadowAnimator.cancel();
+ }
+ mShadowAnimator = ObjectAnimator
+ .ofInt(this, SHADOW_ALPHA, 0, 255)
+ .setDuration(100);
+ mShadowAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mShadowAnimator = null;
+ }
+ });
+ mShadowAnimator.start();
+ }
+
public void animateBackgroundStroke() {
if (mStrokeAlphaAnimator != null) {
mStrokeAlphaAnimator.cancel();