summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3')
-rw-r--r--src/com/android/launcher3/Launcher.java6
-rw-r--r--src/com/android/launcher3/LauncherStateManager.java6
-rw-r--r--src/com/android/launcher3/anim/AlphaUpdateListener.java2
-rw-r--r--src/com/android/launcher3/anim/AnimatorPlaybackController.java21
-rw-r--r--src/com/android/launcher3/anim/Interpolators.java2
-rw-r--r--src/com/android/launcher3/folder/Folder.java4
-rw-r--r--src/com/android/launcher3/folder/FolderAnimationManager.java83
-rw-r--r--src/com/android/launcher3/touch/AbstractStateChangeTouchController.java5
-rw-r--r--src/com/android/launcher3/views/FloatingIconView.java28
9 files changed, 108 insertions, 49 deletions
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 491e5de85..80860455c 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -446,12 +446,16 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
public void reapplyUi() {
+ reapplyUi(true /* cancelCurrentAnimation */);
+ }
+
+ public void reapplyUi(boolean cancelCurrentAnimation) {
if (supportsFakeLandscapeUI()) {
mRotationMode = mStableDeviceProfile == null
? RotationMode.NORMAL : UiFactory.getRotationMode(mDeviceProfile);
}
getRootView().dispatchInsets();
- getStateManager().reapplyState(true /* cancelCurrentAnimation */);
+ getStateManager().reapplyState(cancelCurrentAnimation);
}
@Override
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 848e19fb5..f67350884 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -24,7 +24,8 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.os.Handler;
import android.os.Looper;
-import android.util.Log;
+
+import androidx.annotation.IntDef;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -32,7 +33,6 @@ import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.anim.PropertySetter.AnimatedPropertySetter;
import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.uioverrides.UiFactory;
import java.io.PrintWriter;
@@ -40,8 +40,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import androidx.annotation.IntDef;
-
/**
* TODO: figure out what kind of tests we can write for this
*
diff --git a/src/com/android/launcher3/anim/AlphaUpdateListener.java b/src/com/android/launcher3/anim/AlphaUpdateListener.java
index 8ac9d662c..eabd28369 100644
--- a/src/com/android/launcher3/anim/AlphaUpdateListener.java
+++ b/src/com/android/launcher3/anim/AlphaUpdateListener.java
@@ -27,7 +27,7 @@ import android.view.ViewGroup;
*/
public class AlphaUpdateListener extends AnimationSuccessListener
implements AnimatorUpdateListener {
- private static final float ALPHA_CUTOFF_THRESHOLD = 0.01f;
+ public static final float ALPHA_CUTOFF_THRESHOLD = 0.01f;
private View mView;
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 2c440bba1..4a52795f8 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -26,15 +26,15 @@ import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.util.Log;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.SpringAnimation;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import androidx.dynamicanimation.animation.DynamicAnimation;
-import androidx.dynamicanimation.animation.SpringAnimation;
-
/**
* Helper class to control the playback of an {@link AnimatorSet}, with custom interpolators
* and durations.
@@ -250,6 +250,17 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat
}
}
+ /**
+ * Sets mOnCancelRunnable = null before dispatching the cancel and restoring the runnable. This
+ * is intended to be used only if you need to cancel but want to defer cleaning up yourself.
+ */
+ public void dispatchOnCancelWithoutCancelRunnable() {
+ Runnable onCancel = mOnCancelRunnable;
+ setOnCancelRunnable(null);
+ dispatchOnCancel();
+ setOnCancelRunnable(onCancel);
+ }
+
public void dispatchOnCancel() {
dispatchOnCancelRecursively(mAnim);
}
@@ -283,10 +294,6 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat
mOnCancelRunnable = runnable;
}
- public Runnable getOnCancelRunnable() {
- return mOnCancelRunnable;
- }
-
public void skipToEnd() {
mSkipToEnd = true;
for (SpringAnimation spring : mSprings) {
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index c45cd85aa..fccc12090 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -39,6 +39,7 @@ public class Interpolators {
public static final Interpolator LINEAR = new LinearInterpolator();
public static final Interpolator ACCEL = new AccelerateInterpolator();
+ public static final Interpolator ACCEL_0_75 = new AccelerateInterpolator(0.75f);
public static final Interpolator ACCEL_1_5 = new AccelerateInterpolator(1.5f);
public static final Interpolator ACCEL_2 = new AccelerateInterpolator(2);
@@ -48,6 +49,7 @@ public class Interpolators {
public static final Interpolator DEACCEL_2 = new DecelerateInterpolator(2);
public static final Interpolator DEACCEL_2_5 = new DecelerateInterpolator(2.5f);
public static final Interpolator DEACCEL_3 = new DecelerateInterpolator(3f);
+ public static final Interpolator DEACCEL_5 = new DecelerateInterpolator(5f);
public static final Interpolator ACCEL_DEACCEL = new AccelerateDecelerateInterpolator();
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 6b9e20525..0bd2c9af7 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -148,7 +148,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
public ExtendedEditText mFolderName;
private PageIndicatorDots mPageIndicator;
- private View mFooter;
+ protected View mFooter;
private int mFooterHeight;
// Cell ranks used for drag and drop
@@ -991,7 +991,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
lp.y = top;
}
- private int getContentAreaHeight() {
+ protected int getContentAreaHeight() {
DeviceProfile grid = mLauncher.getDeviceProfile();
int maxContentAreaHeight = grid.availableHeightPx - grid.getTotalWorkspacePadding().y
- mFooterHeight;
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index 9eb06938a..1310d374e 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -59,6 +59,8 @@ import java.util.List;
*/
public class FolderAnimationManager {
+ private static final int FOLDER_NAME_ALPHA_DURATION = 32;
+
private Folder mFolder;
private FolderPagedView mContent;
private GradientDrawable mFolderBackground;
@@ -130,11 +132,19 @@ public class FolderAnimationManager {
* scaleRelativeToDragLayer;
final float finalScale = 1f;
float scale = mIsOpening ? initialScale : finalScale;
- mFolder.setScaleX(scale);
- mFolder.setScaleY(scale);
mFolder.setPivotX(0);
mFolder.setPivotY(0);
+ // Scale the contents of the folder.
+ mFolder.mContent.setScaleX(scale);
+ mFolder.mContent.setScaleY(scale);
+ mFolder.mContent.setPivotX(0);
+ mFolder.mContent.setPivotY(0);
+ mFolder.mFooter.setScaleX(scale);
+ mFolder.mFooter.setScaleY(scale);
+ mFolder.mFooter.setPivotX(0);
+ mFolder.mFooter.setPivotY(0);
+
// We want to create a small X offset for the preview items, so that they follow their
// expected path to their final locations. ie. an icon should not move right, if it's final
// location is to its left. This value is arbitrarily defined.
@@ -143,14 +153,13 @@ public class FolderAnimationManager {
previewItemOffsetX = (int) (lp.width * initialScale - initialSize - previewItemOffsetX);
}
- final int paddingOffsetX = (int) ((mFolder.getPaddingLeft() + mContent.getPaddingLeft())
- * initialScale);
- final int paddingOffsetY = (int) ((mFolder.getPaddingTop() + mContent.getPaddingTop())
- * initialScale);
+ final int paddingOffsetX = (int) (mContent.getPaddingLeft() * initialScale);
+ final int paddingOffsetY = (int) (mContent.getPaddingTop() * initialScale);
- int initialX = folderIconPos.left + mPreviewBackground.getOffsetX() - paddingOffsetX
- - previewItemOffsetX;
- int initialY = folderIconPos.top + mPreviewBackground.getOffsetY() - paddingOffsetY;
+ int initialX = folderIconPos.left + mFolder.getPaddingLeft()
+ + mPreviewBackground.getOffsetX() - paddingOffsetX - previewItemOffsetX;
+ int initialY = folderIconPos.top + mFolder.getPaddingTop()
+ + mPreviewBackground.getOffsetY() - paddingOffsetY;
final float xDistance = initialX - lp.x;
final float yDistance = initialY - lp.y;
@@ -164,11 +173,10 @@ public class FolderAnimationManager {
// Set up the reveal animation that clips the Folder.
int totalOffsetX = paddingOffsetX + previewItemOffsetX;
- Rect startRect = new Rect(
- Math.round(totalOffsetX / initialScale),
- Math.round(paddingOffsetY / initialScale),
- Math.round((totalOffsetX + initialSize) / initialScale),
- Math.round((paddingOffsetY + initialSize) / initialScale));
+ Rect startRect = new Rect(totalOffsetX,
+ paddingOffsetY,
+ Math.round((totalOffsetX + initialSize)),
+ Math.round((paddingOffsetY + initialSize)));
Rect endRect = new Rect(0, 0, lp.width, lp.height);
float finalRadius = ResourceUtils.pxFromDp(2, mContext.getResources().getDisplayMetrics());
@@ -189,17 +197,46 @@ public class FolderAnimationManager {
play(a, getAnimator(mFolder, View.TRANSLATION_X, xDistance, 0f));
play(a, getAnimator(mFolder, View.TRANSLATION_Y, yDistance, 0f));
- play(a, getAnimator(mFolder, SCALE_PROPERTY, initialScale, finalScale));
+ play(a, getAnimator(mFolder.mContent, SCALE_PROPERTY, initialScale, finalScale));
+ play(a, getAnimator(mFolder.mFooter, SCALE_PROPERTY, initialScale, finalScale));
play(a, getAnimator(mFolderBackground, "color", initialColor, finalColor));
play(a, mFolderIcon.mFolderName.createTextAlphaAnimator(!mIsOpening));
play(a, getShape().createRevealAnimator(
mFolder, startRect, endRect, finalRadius, !mIsOpening));
+ // Fade in the folder name, as the text can overlap the icons when grid size is small.
+ mFolder.mFolderName.setAlpha(mIsOpening ? 0f : 1f);
+ play(a, getAnimator(mFolder.mFolderName, View.ALPHA, 0, 1),
+ mIsOpening ? FOLDER_NAME_ALPHA_DURATION : 0,
+ mIsOpening ? mDuration - FOLDER_NAME_ALPHA_DURATION : FOLDER_NAME_ALPHA_DURATION);
+
+ // Translate the footer so that it tracks the bottom of the content.
+ float normalHeight = mFolder.getContentAreaHeight();
+ float scaledHeight = normalHeight * initialScale;
+ float diff = normalHeight - scaledHeight;
+ play(a, getAnimator(mFolder.mFooter, View.TRANSLATION_Y, -diff, 0f));
// Animate the elevation midway so that the shadow is not noticeable in the background.
int midDuration = mDuration / 2;
Animator z = getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0);
play(a, z, mIsOpening ? midDuration : 0, midDuration);
+
+ // Store clip variables
+ CellLayout cellLayout = mContent.getCurrentCellLayout();
+ boolean folderClipChildren = mFolder.getClipChildren();
+ boolean folderClipToPadding = mFolder.getClipToPadding();
+ boolean contentClipChildren = mContent.getClipChildren();
+ boolean contentClipToPadding = mContent.getClipToPadding();
+ boolean cellLayoutClipChildren = cellLayout.getClipChildren();
+ boolean cellLayoutClipPadding = cellLayout.getClipToPadding();
+
+ mFolder.setClipChildren(false);
+ mFolder.setClipToPadding(false);
+ mContent.setClipChildren(false);
+ mContent.setClipToPadding(false);
+ cellLayout.setClipChildren(false);
+ cellLayout.setClipToPadding(false);
+
a.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -207,8 +244,20 @@ public class FolderAnimationManager {
mFolder.setTranslationX(0.0f);
mFolder.setTranslationY(0.0f);
mFolder.setTranslationZ(0.0f);
- mFolder.setScaleX(1f);
- mFolder.setScaleY(1f);
+ mFolder.mContent.setScaleX(1f);
+ mFolder.mContent.setScaleY(1f);
+ mFolder.mFooter.setScaleX(1f);
+ mFolder.mFooter.setScaleY(1f);
+ mFolder.mFooter.setTranslationX(0f);
+ mFolder.mFolderName.setAlpha(1f);
+
+ mFolder.setClipChildren(folderClipChildren);
+ mFolder.setClipToPadding(folderClipToPadding);
+ mContent.setClipChildren(contentClipChildren);
+ mContent.setClipToPadding(contentClipToPadding);
+ cellLayout.setClipChildren(cellLayoutClipChildren);
+ cellLayout.setClipToPadding(cellLayoutClipPadding);
+
}
});
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 60f6ee9c5..f40f9762d 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -413,10 +413,7 @@ public abstract class AbstractStateChangeTouchController
} else {
// Let the state manager know that the animation didn't go to the target state,
// but don't cancel ourselves (we already clean up when the animation completes).
- Runnable onCancel = mCurrentAnimation.getOnCancelRunnable();
- mCurrentAnimation.setOnCancelRunnable(null);
- mCurrentAnimation.dispatchOnCancel();
- mCurrentAnimation.setOnCancelRunnable(onCancel);
+ mCurrentAnimation.dispatchOnCancelWithoutCancelRunnable();
endProgress = 0;
if (progress <= 0) {
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 45c0d9097..49d94f06e 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -560,7 +560,7 @@ public class FloatingIconView extends View implements
* Checks if the icon result is loaded. If true, we set the icon immediately. Else, we add a
* callback to set the icon once the icon result is loaded.
*/
- private void checkIconResult(View originalView, boolean isOpening) {
+ private void checkIconResult(View originalView) {
CancellationSignal cancellationSignal = new CancellationSignal();
if (mIconLoadResult == null) {
@@ -572,9 +572,7 @@ public class FloatingIconView extends View implements
if (mIconLoadResult.isIconLoaded) {
setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge,
mIconLoadResult.iconOffset);
- if (isOpening) {
- hideOriginalView(originalView);
- }
+ hideOriginalView(originalView);
} else {
mIconLoadResult.onIconLoaded = () -> {
if (cancellationSignal.isCanceled()) {
@@ -583,12 +581,8 @@ public class FloatingIconView extends View implements
setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge,
mIconLoadResult.iconOffset);
-
setVisibility(VISIBLE);
- if (isOpening) {
- // Delay swapping views until the icon is loaded to prevent a flash.
- hideOriginalView(originalView);
- }
+ hideOriginalView(originalView);
};
mLoadIconSignal = cancellationSignal;
}
@@ -596,9 +590,9 @@ public class FloatingIconView extends View implements
}
private void hideOriginalView(View originalView) {
- if (originalView instanceof BubbleTextView) {
- ((BubbleTextView) originalView).setIconVisible(false);
- ((BubbleTextView) originalView).setForceHideDot(true);
+ if (originalView instanceof IconLabelDotView) {
+ ((IconLabelDotView) originalView).setIconVisible(false);
+ ((IconLabelDotView) originalView).setForceHideDot(true);
} else {
originalView.setVisibility(INVISIBLE);
}
@@ -674,6 +668,9 @@ public class FloatingIconView extends View implements
}
public void fastFinish() {
+ if (mLoadIconSignal != null) {
+ mLoadIconSignal.cancel();
+ }
if (mEndRunnable != null) {
mEndRunnable.run();
mEndRunnable = null;
@@ -689,6 +686,10 @@ public class FloatingIconView extends View implements
if (mIconLoadResult != null && mIconLoadResult.isIconLoaded) {
setVisibility(View.VISIBLE);
}
+ if (!mIsOpening) {
+ // When closing an app, we want the item on the workspace to be invisible immediately
+ hideOriginalView(mOriginalIcon);
+ }
}
@Override
@@ -798,7 +799,7 @@ public class FloatingIconView extends View implements
// Must be called after the fastFinish listener and end runnable is created so that
// the icon is not left in a hidden state.
if (shouldLoadIcon) {
- view.checkIconResult(originalView, isOpening);
+ view.checkIconResult(originalView);
}
return view;
@@ -842,6 +843,7 @@ public class FloatingIconView extends View implements
@Override
public void onAnimationStart(Animator animation) {
btv.setIconVisible(true);
+ btv.setForceHideDot(true);
}
});
fade.play(ObjectAnimator.ofInt(btv.getIcon(), DRAWABLE_ALPHA, 0, 255));