From d024f9845a0974ab525baad085f316031cd5a742 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Wed, 23 May 2012 18:26:45 -0700 Subject: Cleaning up some reordering issues: -> Reorder solution should never change unless target cell changes -> Simplified code and improved the behaviour when items' jiggle animations switch from one direction to another. These transitions are now seamless and have no more strange delays. Change-Id: I35d70f275d622501851328584bfcb46eec91ff3b --- src/com/android/launcher2/CellLayout.java | 76 ++++++++++++------------------- src/com/android/launcher2/Workspace.java | 13 ++---- 2 files changed, 35 insertions(+), 54 deletions(-) diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java index 4837ddd3a..c7ad92310 100644 --- a/src/com/android/launcher2/CellLayout.java +++ b/src/com/android/launcher2/CellLayout.java @@ -1902,7 +1902,6 @@ public class CellLayout extends ViewGroup { // This method starts or changes the reorder hint animations private void beginOrAdjustHintAnimations(ItemConfiguration solution, View dragView, int delay) { int childCount = mShortcutsAndWidgets.getChildCount(); - int timeForPriorAnimationToComplete = getMaxCompletionTime(); for (int i = 0; i < childCount; i++) { View child = mShortcutsAndWidgets.getChildAt(i); if (child == dragView) continue; @@ -1911,7 +1910,7 @@ public class CellLayout extends ViewGroup { if (c != null) { ReorderHintAnimation rha = new ReorderHintAnimation(child, lp.cellX, lp.cellY, c.x, c.y, c.spanX, c.spanY); - rha.animate(timeForPriorAnimationToComplete); + rha.animate(); } } } @@ -1920,11 +1919,13 @@ public class CellLayout extends ViewGroup { // in a temporary state, and hint at where the item will return to. class ReorderHintAnimation { View child; - float deltaX; - float deltaY; + float finalDeltaX; + float finalDeltaY; + float initDeltaX; + float initDeltaY; + float finalScale; + float initScale; private static final int DURATION = 300; - private int repeatCount; - private boolean cancelOnCycleComplete = false; ValueAnimator va; public ReorderHintAnimation(View child, int cellX0, int cellY0, int cellX1, int cellY1, @@ -1937,72 +1938,73 @@ public class CellLayout extends ViewGroup { final int y1 = mTmpPoint[1]; final int dX = x1 - x0; final int dY = y1 - y0; - deltaX = 0; - deltaY = 0; + finalDeltaX = 0; + finalDeltaY = 0; if (dX == dY && dX == 0) { } else { if (dY == 0) { - deltaX = - Math.signum(dX) * mReorderHintAnimationMagnitude; + finalDeltaX = - Math.signum(dX) * mReorderHintAnimationMagnitude; } else if (dX == 0) { - deltaY = - Math.signum(dY) * mReorderHintAnimationMagnitude; + finalDeltaY = - Math.signum(dY) * mReorderHintAnimationMagnitude; } else { double angle = Math.atan( (float) (dY) / dX); - deltaX = (int) (- Math.signum(dX) * + finalDeltaX = (int) (- Math.signum(dX) * Math.abs(Math.cos(angle) * mReorderHintAnimationMagnitude)); - deltaY = (int) (- Math.signum(dY) * + finalDeltaY = (int) (- Math.signum(dY) * Math.abs(Math.sin(angle) * mReorderHintAnimationMagnitude)); } } + initDeltaX = child.getTranslationX(); + initDeltaY = child.getTranslationY(); + finalScale = 1.0f - 4.0f / child.getWidth(); + initScale = child.getScaleX(); + child.setPivotY(child.getMeasuredHeight() * 0.5f); child.setPivotX(child.getMeasuredWidth() * 0.5f); this.child = child; } - void animate(int delay) { + void animate() { if (mShakeAnimators.containsKey(child)) { ReorderHintAnimation oldAnimation = mShakeAnimators.get(child); - oldAnimation.completeAnimation(); + oldAnimation.cancel(); mShakeAnimators.remove(child); } - if (deltaX == 0 && deltaY == 0) { + if (finalDeltaX == 0 && finalDeltaY == 0) { return; } va = ValueAnimator.ofFloat(0f, 1f); va.setRepeatMode(ValueAnimator.REVERSE); va.setRepeatCount(ValueAnimator.INFINITE); va.setDuration(DURATION); - va.setStartDelay((int) ((Math.max(REORDER_ANIMATION_DURATION, delay) - + Math.random() * 60))); + va.setStartDelay((int) (Math.random() * 60)); va.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float r = ((Float) animation.getAnimatedValue()).floatValue(); - float x = r * deltaX; - float y = r * deltaY; + float x = r * finalDeltaX + (1 - r) * initDeltaX; + float y = r * finalDeltaY + (1 - r) * initDeltaY; child.setTranslationX(x); child.setTranslationY(y); - float sf = 4.0f / child.getWidth(); - float s = 1.0f - r * sf; + float s = r * finalScale + (1 - r) * initScale; child.setScaleX(s); child.setScaleY(s); } }); va.addListener(new AnimatorListenerAdapter() { public void onAnimationRepeat(Animator animation) { - repeatCount++; // We make sure to end only after a full period - if (cancelOnCycleComplete && repeatCount % 2 == 0) { - va.cancel(); - } + initDeltaX = 0; + initDeltaY = 0; + initScale = 1.0f; } }); mShakeAnimators.put(child, this); va.start(); } - - private void completeAnimation() { - cancelOnCycleComplete = true; + private void cancel() { + va.cancel(); } private void completeAnimationImmediately() { va.cancel(); @@ -2018,16 +2020,6 @@ public class CellLayout extends ViewGroup { s.setInterpolator(new android.view.animation.DecelerateInterpolator(1.5f)); s.start(); } - - - // Returns the time required to complete the current oscillating animation - private int completionTime() { - if (repeatCount % 2 == 0) { - return (int) (va.getDuration() - va.getCurrentPlayTime() + DURATION); - } else { - return (int) (va.getDuration() - va.getCurrentPlayTime()); - } - } } private void completeAndClearReorderHintAnimations() { @@ -2037,14 +2029,6 @@ public class CellLayout extends ViewGroup { mShakeAnimators.clear(); } - private int getMaxCompletionTime() { - int maxTime = 0; - for (ReorderHintAnimation a: mShakeAnimators.values()) { - maxTime = Math.max(maxTime, a.completionTime()); - } - return maxTime; - } - private void commitTempPlacement() { for (int i = 0; i < mCountX; i++) { for (int j = 0; j < mCountY; j++) { diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 047c16c71..f562cbccb 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -2770,7 +2770,8 @@ public class Workspace extends SmoothPagedView ItemInfo info = (ItemInfo) d.dragInfo; mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], - (int) mDragViewVisualCenter[1], 1, 1, mDragTargetLayout, mTargetCell); + (int) mDragViewVisualCenter[1], item.spanX, item.spanY, + mDragTargetLayout, mTargetCell); setCurrentDropOverCell(mTargetCell[0], mTargetCell[1]); @@ -2790,11 +2791,6 @@ public class Workspace extends SmoothPagedView minSpanY = item.minSpanY; } - int[] reorderPosition = new int[2]; - reorderPosition = findNearestArea((int) mDragViewVisualCenter[0], - (int) mDragViewVisualCenter[1], item.spanX, item.spanY, mDragTargetLayout, - reorderPosition); - boolean nearestDropOccupied = mDragTargetLayout.isNearestDropLocationOccupied((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX, item.spanY, child, mTargetCell); @@ -2805,8 +2801,9 @@ public class Workspace extends SmoothPagedView mTargetCell[0], mTargetCell[1], item.spanX, item.spanY, false, d.dragView.getDragVisualizeOffset(), d.dragView.getDragRegion()); } else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER) - && !mReorderAlarm.alarmPending() && (mLastReorderX != reorderPosition[0] || - mLastReorderY != reorderPosition[1])) { + && !mReorderAlarm.alarmPending() && (mLastReorderX != mTargetCell[0] || + mLastReorderY != mTargetCell[1])) { + // Otherwise, if we aren't adding to or creating a folder and there's no pending // reorder, then we schedule a reorder ReorderAlarmListener listener = new ReorderAlarmListener(mDragViewVisualCenter, -- cgit v1.2.3