From 1721ccf3854b48d27a7d2c78df2daba14945960d Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 8 Jun 2021 12:57:40 -0700 Subject: [PATCH] Simplifying the drop animation code > Removing some unused parameters Bug: 190524398 Test: Manual Change-Id: Iea0c2e7a9d30a10fd7443ea57992c59ea60badf8 --- .../android/launcher3/ButtonDropTarget.java | 11 +- src/com/android/launcher3/Workspace.java | 8 +- .../launcher3/dragndrop/DragLayer.java | 187 +++++++----------- .../android/launcher3/folder/FolderIcon.java | 8 +- .../launcher3/util/FlingAnimation.java | 44 ++--- .../launcher3/views/BaseDragLayer.java | 14 +- 6 files changed, 105 insertions(+), 167 deletions(-) diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java index 7db34a5613..e9f50c7e9e 100644 --- a/src/com/android/launcher3/ButtonDropTarget.java +++ b/src/com/android/launcher3/ButtonDropTarget.java @@ -36,8 +36,6 @@ import android.view.accessibility.AccessibilityEvent; import android.widget.PopupWindow; import android.widget.TextView; -import androidx.appcompat.content.res.AppCompatResources; - import com.android.launcher3.anim.Interpolators; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; @@ -238,11 +236,8 @@ public abstract class ButtonDropTarget extends TextView return; } final DragLayer dragLayer = mLauncher.getDragLayer(); - final Rect from = new Rect(); - dragLayer.getViewRectRelativeToSelf(d.dragView, from); - final Rect to = getIconRect(d); - final float scale = (float) to.width() / from.width(); + final float scale = (float) to.width() / d.dragView.getMeasuredWidth(); d.dragView.detachContentView(/* reattachToPreviousParent= */ true); mDropTargetBar.deferOnDragEnd(); @@ -252,9 +247,9 @@ public abstract class ButtonDropTarget extends TextView mLauncher.getStateManager().goToState(NORMAL); }; - dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f, + dragLayer.animateView(d.dragView, to, scale, 0.1f, 0.1f, DRAG_VIEW_DROP_DURATION, - Interpolators.DEACCEL_2, Interpolators.LINEAR, onAnimationEndRunnable, + Interpolators.DEACCEL_2, onAnimationEndRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 9a8f3ddc02..06bd66e5b6 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -17,6 +17,7 @@ package com.android.launcher3; import static androidx.annotation.VisibleForTesting.PROTECTED; + import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; import static com.android.launcher3.LauncherState.ALL_APPS; @@ -2684,9 +2685,6 @@ public class Workspace extends PagedView public void animateWidgetDrop(ItemInfo info, CellLayout cellLayout, final DragView dragView, final Runnable onCompleteRunnable, int animationType, final View finalView, boolean external) { - Rect from = new Rect(); - mLauncher.getDragLayer().getViewRectRelativeToSelf(dragView, from); - int[] finalPos = new int[2]; float scaleXY[] = new float[2]; boolean scalePreview = !(info instanceof PendingAddShortcutInfo); @@ -2730,8 +2728,8 @@ public class Workspace extends PagedView } } }; - dragLayer.animateViewIntoPosition(dragView, from.left, from.top, finalPos[0], - finalPos[1], 1, 1, 1, scaleXY[0], scaleXY[1], onComplete, endStyle, + dragLayer.animateViewIntoPosition(dragView, finalPos[0], + finalPos[1], 1, scaleXY[0], scaleXY[1], onComplete, endStyle, duration, this); } } diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 011325d6cf..5ee42037b0 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -17,14 +17,19 @@ package com.android.launcher3.dragndrop; +import static android.animation.ObjectAnimator.ofFloat; + +import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; +import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y; +import static com.android.launcher3.Utilities.mapRange; +import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5; import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.animation.TypeEvaluator; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; @@ -44,10 +49,11 @@ import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.ShortcutAndWidgetContainer; import com.android.launcher3.Workspace; +import com.android.launcher3.anim.PendingAnimation; +import com.android.launcher3.anim.SpringProperty; import com.android.launcher3.folder.Folder; import com.android.launcher3.graphics.Scrim; import com.android.launcher3.keyboard.ViewGroupFocusHelper; -import com.android.launcher3.util.Thunk; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; @@ -69,11 +75,9 @@ public class DragLayer extends BaseDragLayer { private DragController mDragController; // Variables relating to animation of views after drop - private ValueAnimator mDropAnim = null; + private Animator mDropAnim = null; - @Thunk DragView mDropView = null; - @Thunk int mAnchorViewInitialScrollX = 0; - @Thunk View mAnchorView = null; + private DragView mDropView = null; private boolean mHoverPointClosesFolder = false; @@ -220,12 +224,7 @@ public class DragLayer extends BaseDragLayer { public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha, float scaleX, float scaleY, int animationEndStyle, Runnable onFinishRunnable, int duration) { - Rect r = new Rect(); - getViewRectRelativeToSelf(dragView, r); - final int fromX = r.left; - final int fromY = r.top; - - animateViewIntoPosition(dragView, fromX, fromY, pos[0], pos[1], alpha, 1, 1, scaleX, scaleY, + animateViewIntoPosition(dragView, pos[0], pos[1], alpha, scaleX, scaleY, onFinishRunnable, animationEndStyle, duration, null); } @@ -241,11 +240,6 @@ public class DragLayer extends BaseDragLayer { parentChildren.measureChild(child); parentChildren.layoutChild(child); - Rect dragViewBounds = new Rect(); - getViewRectRelativeToSelf(dragView, dragViewBounds); - final int fromX = dragViewBounds.left; - final int fromY = dragViewBounds.top; - float coord[] = new float[2]; float childScale = child.getScaleX(); @@ -288,51 +282,50 @@ public class DragLayer extends BaseDragLayer { child.setVisibility(INVISIBLE); Runnable onCompleteRunnable = () -> child.setVisibility(VISIBLE); - animateViewIntoPosition(dragView, fromX, fromY, toX, toY, 1, 1, 1, toScale, toScale, + animateViewIntoPosition(dragView, toX, toY, 1, toScale, toScale, onCompleteRunnable, ANIMATION_END_DISAPPEAR, duration, anchorView); } - public void animateViewIntoPosition(final DragView view, final int fromX, final int fromY, - final int toX, final int toY, float finalAlpha, float initScaleX, float initScaleY, - float finalScaleX, float finalScaleY, Runnable onCompleteRunnable, - int animationEndStyle, int duration, View anchorView) { - Rect from = new Rect(fromX, fromY, fromX + - view.getMeasuredWidth(), fromY + view.getMeasuredHeight()); - Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight()); - animateView(view, from, to, finalAlpha, initScaleX, initScaleY, finalScaleX, finalScaleY, duration, - null, null, onCompleteRunnable, animationEndStyle, anchorView); - } - /** * This method animates a view at the end of a drag and drop animation. - * + */ + public void animateViewIntoPosition(final DragView view, + final int toX, final int toY, float finalAlpha, + float finalScaleX, float finalScaleY, Runnable onCompleteRunnable, + int animationEndStyle, int duration, View anchorView) { + Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight()); + animateView(view, to, finalAlpha, finalScaleX, finalScaleY, duration, + null, onCompleteRunnable, animationEndStyle, anchorView); + } + + /** + * This method animates a view at the end of a drag and drop animation. * @param view The view to be animated. This view is drawn directly into DragLayer, and so * doesn't need to be a child of DragLayer. - * @param from The initial location of the view. Only the left and top parameters are used. * @param to The final location of the view. Only the left and top parameters are used. This - * location doesn't account for scaling, and so should be centered about the desired - * final location (including scaling). +* location doesn't account for scaling, and so should be centered about the desired +* final location (including scaling). * @param finalAlpha The final alpha of the view, in case we want it to fade as it animates. * @param finalScaleX The final scale of the view. The view is scaled about its center. * @param finalScaleY The final scale of the view. The view is scaled about its center. * @param duration The duration of the animation. * @param motionInterpolator The interpolator to use for the location of the view. - * @param alphaInterpolator The interpolator to use for the alpha of the view. * @param onCompleteRunnable Optional runnable to run on animation completion. * @param animationEndStyle Whether or not to fade out the view once the animation completes. - * {@link #ANIMATION_END_DISAPPEAR} or {@link #ANIMATION_END_REMAIN_VISIBLE}. +* {@link #ANIMATION_END_DISAPPEAR} or {@link #ANIMATION_END_REMAIN_VISIBLE}. * @param anchorView If not null, this represents the view which the animated view stays - * anchored to in case scrolling is currently taking place. Note: currently this is - * only used for the X dimension for the case of the workspace. */ - public void animateView(final DragView view, final Rect from, final Rect to, - final float finalAlpha, final float initScaleX, final float initScaleY, - final float finalScaleX, final float finalScaleY, int duration, - final Interpolator motionInterpolator, final Interpolator alphaInterpolator, - final Runnable onCompleteRunnable, final int animationEndStyle, View anchorView) { + public void animateView(final DragView view, final Rect to, + final float finalAlpha, final float finalScaleX, final float finalScaleY, int duration, + final Interpolator motionInterpolator, final Runnable onCompleteRunnable, + final int animationEndStyle, View anchorView) { + view.cancelAnimation(); + view.requestLayout(); + + final int[] from = getViewLocationRelativeToSelf(view); // Calculate the duration of the animation based on the object's distance - final float dist = (float) Math.hypot(to.left - from.left, to.top - from.top); + final float dist = (float) Math.hypot(to.left - from[0], to.top - from[1]); final Resources res = getResources(); final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist); @@ -346,93 +339,45 @@ public class DragLayer extends BaseDragLayer { } // Fall back to cubic ease out interpolator for the animation if none is specified - TimeInterpolator interpolator = null; - if (alphaInterpolator == null || motionInterpolator == null) { - interpolator = DEACCEL_1_5; - } + TimeInterpolator interpolator = + motionInterpolator == null ? DEACCEL_1_5 : motionInterpolator; // Animate the view - final float initAlpha = view.getAlpha(); - final float dropViewScale = view.getScaleX(); - AnimatorUpdateListener updateCb = new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - final float percent = (Float) animation.getAnimatedValue(); - final int width = view.getMeasuredWidth(); - final int height = view.getMeasuredHeight(); + PendingAnimation anim = new PendingAnimation(duration); + anim.add(ofFloat(view, View.SCALE_X, finalScaleX), interpolator, SpringProperty.DEFAULT); + anim.add(ofFloat(view, View.SCALE_Y, finalScaleY), interpolator, SpringProperty.DEFAULT); + anim.setViewAlpha(view, finalAlpha, interpolator); + anim.setFloat(view, VIEW_TRANSLATE_Y, to.top, interpolator); - float alphaPercent = alphaInterpolator == null ? percent : - alphaInterpolator.getInterpolation(percent); - float motionPercent = motionInterpolator == null ? percent : - motionInterpolator.getInterpolation(percent); - - float initialScaleX = initScaleX * dropViewScale; - float initialScaleY = initScaleY * dropViewScale; - float scaleX = finalScaleX * percent + initialScaleX * (1 - percent); - float scaleY = finalScaleY * percent + initialScaleY * (1 - percent); - float alpha = finalAlpha * alphaPercent + initAlpha * (1 - alphaPercent); - - float fromLeft = from.left + (initialScaleX - 1f) * width / 2; - float fromTop = from.top + (initialScaleY - 1f) * height / 2; - - int x = (int) (fromLeft + Math.round(((to.left - fromLeft) * motionPercent))); - int y = (int) (fromTop + Math.round(((to.top - fromTop) * motionPercent))); - - int anchorAdjust = mAnchorView == null ? 0 : (int) (mAnchorView.getScaleX() * - (mAnchorViewInitialScrollX - mAnchorView.getScrollX())); - - int xPos = x - mDropView.getScrollX() + anchorAdjust; - int yPos = y - mDropView.getScrollY(); - - mDropView.setTranslationX(xPos); - mDropView.setTranslationY(yPos); - mDropView.setScaleX(scaleX); - mDropView.setScaleY(scaleY); - mDropView.setAlpha(alpha); - } - }; - animateView(view, updateCb, duration, interpolator, onCompleteRunnable, animationEndStyle, - anchorView); + ObjectAnimator xMotion = ofFloat(view, VIEW_TRANSLATE_X, to.left); + if (anchorView != null) { + final int startScroll = anchorView.getScrollX(); + TypeEvaluator evaluator = (f, s, e) -> mapRange(f, s, e) + + (anchorView.getScaleX() * (startScroll - anchorView.getScrollX())); + xMotion.setEvaluator(evaluator); + } + anim.add(xMotion, interpolator, SpringProperty.DEFAULT); + if (onCompleteRunnable != null) { + anim.addListener(forEndCallback(onCompleteRunnable)); + } + playDropAnimation(view, anim.buildAnim(), animationEndStyle); } - public void animateView(final DragView view, AnimatorUpdateListener updateCb, int duration, - TimeInterpolator interpolator, final Runnable onCompleteRunnable, - final int animationEndStyle, View anchorView) { + /** + * Runs a previously constructed drop animation + */ + public void playDropAnimation(final DragView view, Animator animator, int animationEndStyle) { // Clean up the previous animations if (mDropAnim != null) mDropAnim.cancel(); // Show the drop view if it was previously hidden mDropView = view; - mDropView.cancelAnimation(); - mDropView.requestLayout(); - - // Set the anchor view if the page is scrolling - if (anchorView != null) { - mAnchorViewInitialScrollX = anchorView.getScrollX(); - } - mAnchorView = anchorView; - // Create and start the animation - mDropAnim = new ValueAnimator(); - mDropAnim.setInterpolator(interpolator); - mDropAnim.setDuration(duration); - mDropAnim.setFloatValues(0f, 1f); - mDropAnim.addUpdateListener(updateCb); - mDropAnim.addListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animation) { - if (onCompleteRunnable != null) { - onCompleteRunnable.run(); - } - switch (animationEndStyle) { - case ANIMATION_END_DISAPPEAR: - clearAnimatedView(); - break; - case ANIMATION_END_REMAIN_VISIBLE: - break; - } - mDropAnim = null; - } - }); + mDropAnim = animator; + mDropAnim.addListener(forEndCallback(() -> mDropAnim = null)); + if (animationEndStyle == ANIMATION_END_DISAPPEAR) { + mDropAnim.addListener(forEndCallback(this::clearAnimatedView)); + } mDropAnim.start(); } diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index 6b12d86d13..a526176856 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -336,8 +336,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel if (animateView != null && mActivity instanceof Launcher) { final Launcher launcher = (Launcher) mActivity; DragLayer dragLayer = launcher.getDragLayer(); - Rect from = new Rect(); - dragLayer.getViewRectRelativeToSelf(animateView, from); Rect to = finalRect; if (to == null) { to = new Rect(); @@ -402,9 +400,9 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel finalScale *= containerScale; } - dragLayer.animateView(animateView, from, to, finalAlpha, - 1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION, - Interpolators.DEACCEL_2, Interpolators.ACCEL_2, + dragLayer.animateView(animateView, to, finalAlpha, + finalScale, finalScale, DROP_IN_ANIMATION_DURATION, + Interpolators.DEACCEL_2, null, DragLayer.ANIMATION_END_DISAPPEAR, null); mFolder.hideItem(item); diff --git a/src/com/android/launcher3/util/FlingAnimation.java b/src/com/android/launcher3/util/FlingAnimation.java index c9aa51c0de..ac864e91b3 100644 --- a/src/com/android/launcher3/util/FlingAnimation.java +++ b/src/com/android/launcher3/util/FlingAnimation.java @@ -1,12 +1,14 @@ package com.android.launcher3.util; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.graphics.PointF; import android.graphics.Rect; +import android.graphics.RectF; import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; @@ -35,7 +37,7 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable { protected final float mUX, mUY; protected Rect mIconRect; - protected Rect mFrom; + protected RectF mFrom; protected int mDuration; protected float mAnimationTimeFraction; @@ -55,17 +57,17 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable { @Override public void run() { mIconRect = mDropTarget.getIconRect(mDragObject); + mDragObject.dragView.cancelAnimation(); + mDragObject.dragView.requestLayout(); // Initiate from - mFrom = new Rect(); - mDragLayer.getViewRectRelativeToSelf(mDragObject.dragView, mFrom); - float scale = mDragObject.dragView.getScaleX(); - float xOffset = ((scale - 1f) * mDragObject.dragView.getMeasuredWidth()) / 2f; - float yOffset = ((scale - 1f) * mDragObject.dragView.getMeasuredHeight()) / 2f; - mFrom.left += xOffset; - mFrom.right -= xOffset; - mFrom.top += yOffset; - mFrom.bottom -= yOffset; + Rect from = new Rect(); + mDragLayer.getViewRectRelativeToSelf(mDragObject.dragView, from); + + mFrom = new RectF(from); + mFrom.inset( + ((1 - mDragObject.dragView.getScaleX()) * from.width()) / 2f, + ((1 - mDragObject.dragView.getScaleY()) * from.height()) / 2f); mDuration = Math.abs(mUY) > Math.abs(mUX) ? initFlingUpDuration() : initFlingLeftDuration(); mAnimationTimeFraction = ((float) mDuration) / (mDuration + DRAG_END_DELAY); @@ -95,17 +97,15 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable { } }; - Runnable onAnimationEndRunnable = new Runnable() { - @Override - public void run() { - mLauncher.getStateManager().goToState(NORMAL); - mDropTarget.completeDrop(mDragObject); - } - }; - mDropTarget.onDrop(mDragObject, mDragOptions); - mDragLayer.animateView(mDragObject.dragView, this, duration, tInterpolator, - onAnimationEndRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null); + ValueAnimator anim = ValueAnimator.ofFloat(0, 1); + anim.setDuration(duration).setInterpolator(tInterpolator); + anim.addUpdateListener(this); + anim.addListener(forEndCallback(() -> { + mLauncher.getStateManager().goToState(NORMAL); + mDropTarget.completeDrop(mDragObject); + })); + mDragLayer.playDropAnimation(mDragObject.dragView, anim, DragLayer.ANIMATION_END_DISAPPEAR); } /** @@ -129,7 +129,7 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable { } double t = (-mUY - Math.sqrt(d)) / mAY; - float sX = -mFrom.exactCenterX() + mIconRect.exactCenterX(); + float sX = -mFrom.centerX() + mIconRect.exactCenterX(); // Find horizontal acceleration such that: u*t + a*t*t/2 = s mAX = (float) ((sX - t * mUX) * 2 / (t * t)); @@ -157,7 +157,7 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable { } double t = (-mUX - Math.sqrt(d)) / mAX; - float sY = -mFrom.exactCenterY() + mIconRect.exactCenterY(); + float sY = -mFrom.centerY() + mIconRect.exactCenterY(); // Find vertical acceleration such that: u*t + a*t*t/2 = s mAY = (float) ((sY - t * mUY) * 2 / (t * t)); diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 01c0b562e1..76dfb3ce2a 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -430,18 +430,20 @@ public abstract class BaseDragLayer } public void getViewRectRelativeToSelf(View v, Rect r) { + int[] loc = getViewLocationRelativeToSelf(v); + r.set(loc[0], loc[1], loc[0] + v.getMeasuredWidth(), loc[1] + v.getMeasuredHeight()); + } + + protected int[] getViewLocationRelativeToSelf(View v) { int[] loc = new int[2]; getLocationInWindow(loc); int x = loc[0]; int y = loc[1]; v.getLocationInWindow(loc); - int vX = loc[0]; - int vY = loc[1]; - - int left = vX - x; - int top = vY - y; - r.set(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight()); + loc[0] -= x; + loc[1] -= y; + return loc; } @Override