From 42c29aedf2b518c4317fc534f3c87711b57bc9b5 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 6 Feb 2012 16:43:52 -0800 Subject: Animating the drag view scale up and down when dragging items. - Also fixing up how we draw the drag view alpha Change-Id: Ied82aec9d52274b0fe65c989eab818b0264a9eb2 --- .../android/launcher2/AppsCustomizePagedView.java | 8 -- src/com/android/launcher2/DragController.java | 4 +- src/com/android/launcher2/DragLayer.java | 85 ++++++++++------------ src/com/android/launcher2/DragView.java | 40 ++++++---- src/com/android/launcher2/DropTarget.java | 3 + src/com/android/launcher2/FolderIcon.java | 11 +-- src/com/android/launcher2/InfoDropTarget.java | 4 + src/com/android/launcher2/Workspace.java | 4 +- 8 files changed, 81 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java index 7cfe3be2f..8db1ab694 100644 --- a/src/com/android/launcher2/AppsCustomizePagedView.java +++ b/src/com/android/launcher2/AppsCustomizePagedView.java @@ -201,7 +201,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen private Canvas mCanvas; private Drawable mDefaultWidgetBackground; private IconCache mIconCache; - private int mDragViewMultiplyColor; // Dimens private int mContentWidth; @@ -243,7 +242,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen Resources resources = context.getResources(); mDefaultWidgetBackground = resources.getDrawable(R.drawable.default_widget_preview_holo); mAppIconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size); - mDragViewMultiplyColor = resources.getColor(R.color.drag_view_multiply_color); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0); mMaxAppCellCountX = a.getInt(R.styleable.AppsCustomizePagedView_maxAppCellCountX, -1); @@ -580,9 +578,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // Save the preview for the outline generation, then dim the preview outline = Bitmap.createScaledBitmap(preview, preview.getWidth(), preview.getHeight(), false); - mCanvas.setBitmap(preview); - mCanvas.drawColor(mDragViewMultiplyColor, PorterDuff.Mode.MULTIPLY); - mCanvas.setBitmap(null); // Start the drag alphaClipPaint = null; @@ -908,9 +903,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen d.setBounds(x, y, x + w, y + h); d.draw(c); d.setBounds(oldBounds); // Restore the bounds - if (multiplyColor != 0xFFFFFFFF) { - c.drawColor(mDragViewMultiplyColor, PorterDuff.Mode.MULTIPLY); - } c.setBitmap(null); } } diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java index 8658eebae..425f301ae 100644 --- a/src/com/android/launcher2/DragController.java +++ b/src/com/android/launcher2/DragController.java @@ -394,7 +394,9 @@ public class DragController { listener.onDragEnd(); } if (mDragObject.dragView != null) { - mDragObject.dragView.remove(); + if (!mDragObject.deferDragViewCleanupPostAnimation) { + mDragObject.dragView.remove(); + } mDragObject.dragView = null; } } diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java index c315b6018..05596ef67 100644 --- a/src/com/android/launcher2/DragLayer.java +++ b/src/com/android/launcher2/DragLayer.java @@ -62,13 +62,10 @@ public class DragLayer extends FrameLayout { private ValueAnimator mDropAnim = null; private ValueAnimator mFadeOutAnim = null; private TimeInterpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f); - private View mDropView = null; + private DragView mDropView = null; private int mAnchorViewInitialScrollX = 0; private View mAnchorView = null; - private int[] mDropViewPos = new int[2]; - private float mDropViewScale; - private float mDropViewAlpha; private boolean mHoverPointClosesFolder = false; private Rect mHitRect = new Rect(); private int mWorkspaceIndex = -1; @@ -490,7 +487,7 @@ public class DragLayer extends FrameLayout { onCompleteRunnable, true, duration, anchorView); } - private void animateViewIntoPosition(final View view, final int fromX, final int fromY, + private void animateViewIntoPosition(final DragView view, final int fromX, final int fromY, final int toX, final int toY, float finalScale, Runnable onCompleteRunnable, boolean fadeOut, int duration, View anchorView) { Rect from = new Rect(fromX, fromY, fromX + @@ -521,10 +518,10 @@ public class DragLayer extends FrameLayout { * 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 View view, final Rect from, final Rect to, final float finalAlpha, - final float finalScale, int duration, final Interpolator motionInterpolator, - final Interpolator alphaInterpolator, final Runnable onCompleteRunnable, - final boolean fadeOut, View anchorView) { + public void animateView(final DragView view, final Rect from, final Rect to, + final float finalAlpha, final float finalScale, int duration, + final Interpolator motionInterpolator, final Interpolator alphaInterpolator, + final Runnable onCompleteRunnable, final boolean fadeOut, View anchorView) { // Calculate the duration of the animation based on the object's distance final float dist = (float) Math.sqrt(Math.pow(to.left - from.left, 2) + Math.pow(to.top - from.top, 2)); @@ -547,8 +544,10 @@ public class DragLayer extends FrameLayout { mFadeOutAnim.cancel(); } + // Show the drop view if it was previously hidden mDropView = view; - final float initialAlpha = view.getAlpha(); + mDropView.cancelAnimation(); + mDropView.resetLayoutParams(); mDropAnim = new ValueAnimator(); if (alphaInterpolator == null || motionInterpolator == null) { mDropAnim.setInterpolator(mCubicEaseOutInterpolator); @@ -559,29 +558,39 @@ public class DragLayer extends FrameLayout { } mAnchorView = anchorView; + final float initialAlpha = view.getAlpha(); + final float initialScale = mDropView.getScaleX(); + mDropAnim.setDuration(duration); mDropAnim.setFloatValues(0.0f, 1.0f); mDropAnim.removeAllUpdateListeners(); mDropAnim.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { final float percent = (Float) animation.getAnimatedValue(); - // Invalidate the old position - int width = view.getMeasuredWidth(); - int height = view.getMeasuredHeight(); - invalidate(mDropViewPos[0], mDropViewPos[1], - mDropViewPos[0] + width, mDropViewPos[1] + height); + final int width = view.getMeasuredWidth(); + final int height = view.getMeasuredHeight(); float alphaPercent = alphaInterpolator == null ? percent : alphaInterpolator.getInterpolation(percent); float motionPercent = motionInterpolator == null ? percent : motionInterpolator.getInterpolation(percent); - - mDropViewPos[0] = from.left + (int) Math.round(((to.left - from.left) * motionPercent)); - mDropViewPos[1] = from.top + (int) Math.round(((to.top - from.top) * motionPercent)); - mDropViewScale = percent * finalScale + (1 - percent); - mDropViewAlpha = alphaPercent * finalAlpha + (1 - alphaPercent) * initialAlpha; - invalidate(mDropViewPos[0], mDropViewPos[1], - mDropViewPos[0] + width, mDropViewPos[1] + height); + float scale = finalScale * percent + initialScale * (1 - percent); + float alpha = finalAlpha * alphaPercent + initialAlpha * (1 - alphaPercent); + + float fromLeft = from.left + (initialScale - 1f) * width / 2; + float fromTop = from.top + (initialScale - 1f) * height / 2; + int x = (int) (fromLeft + Math.round(((to.left - fromLeft) * motionPercent))); + int y = (int) (fromTop + Math.round(((to.top - fromTop) * motionPercent))); + + int xPos = x - mDropView.getScrollX() + (mAnchorView != null + ? (mAnchorViewInitialScrollX - mAnchorView.getScrollX()) : 0); + int yPos = y - mDropView.getScrollY(); + mDropView.setTranslationX(xPos); + mDropView.setTranslationY(yPos); + mDropView.setScaleX(scale); + mDropView.setScaleY(scale); + mDropView.setAlpha(alpha); + invalidate(); } }); mDropAnim.addListener(new AnimatorListenerAdapter() { @@ -592,6 +601,7 @@ public class DragLayer extends FrameLayout { if (fadeOut) { fadeOutDragView(); } else { + mDropView.remove(); mDropView = null; } } @@ -607,15 +617,15 @@ public class DragLayer extends FrameLayout { mFadeOutAnim.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { final float percent = (Float) animation.getAnimatedValue(); - mDropViewAlpha = 1 - percent; - int width = mDropView.getMeasuredWidth(); - int height = mDropView.getMeasuredHeight(); - invalidate(mDropViewPos[0], mDropViewPos[1], - mDropViewPos[0] + width, mDropViewPos[1] + height); + + float alpha = 1 - percent; + mDropView.setAlpha(alpha); + invalidate(); } }); mFadeOutAnim.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { + mDropView.remove(); mDropView = null; } }); @@ -665,25 +675,4 @@ public class DragLayer extends FrameLayout { return i; } } - - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - if (mDropView != null) { - // We are animating an item that was just dropped on the home screen. - // Render its View in the current animation position. - canvas.save(Canvas.MATRIX_SAVE_FLAG); - final int xPos = mDropViewPos[0] - mDropView.getScrollX() + (mAnchorView != null - ? (mAnchorViewInitialScrollX - mAnchorView.getScrollX()) : 0); - final int yPos = mDropViewPos[1] - mDropView.getScrollY(); - int width = mDropView.getMeasuredWidth(); - int height = mDropView.getMeasuredHeight(); - canvas.translate(xPos, yPos); - canvas.translate((1 - mDropViewScale) * width / 2, (1 - mDropViewScale) * height / 2); - canvas.scale(mDropViewScale, mDropViewScale); - mDropView.setAlpha(mDropViewAlpha); - mDropView.draw(canvas); - canvas.restore(); - } - } } diff --git a/src/com/android/launcher2/DragView.java b/src/com/android/launcher2/DragView.java index a3063b6e9..7be70a25a 100644 --- a/src/com/android/launcher2/DragView.java +++ b/src/com/android/launcher2/DragView.java @@ -32,6 +32,8 @@ import android.view.animation.DecelerateInterpolator; import com.android.launcher.R; public class DragView extends View { + private static float sDragAlpha = 0.8f; + private Bitmap mBitmap; private Paint mPaint; private int mRegistrationX; @@ -65,20 +67,13 @@ public class DragView extends View { mDragLayer = launcher.getDragLayer(); final Resources res = getResources(); - final int dragScale = res.getInteger(R.integer.config_dragViewExtraPixels); - - Matrix scale = new Matrix(); - final float scaleFactor = (width + dragScale) / width; - if (scaleFactor != 1.0f) { - scale.setScale(scaleFactor, scaleFactor); - } - - final int offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX); - final int offsetY = res.getDimensionPixelSize(R.dimen.dragViewOffsetY); + final float scale = res.getInteger(R.integer.config_dragViewScaleFactor) / 100f; + final float offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX); + final float offsetY = res.getDimensionPixelSize(R.dimen.dragViewOffsetY); // Animate the view into the correct position mAnim = ValueAnimator.ofFloat(0.0f, 1.0f); - mAnim.setDuration(110); + mAnim.setDuration(150); mAnim.setInterpolator(new DecelerateInterpolator(2.5f)); mAnim.addUpdateListener(new AnimatorUpdateListener() { @Override @@ -90,6 +85,9 @@ public class DragView extends View { mOffsetX += deltaX; mOffsetY += deltaY; + setScaleX(1f + (value * (scale - 1f))); + setScaleY(1f + (value * (scale - 1f))); + setAlpha(sDragAlpha * value + (1f - value)); if (getParent() == null) { animation.cancel(); @@ -97,12 +95,14 @@ public class DragView extends View { DragLayer.LayoutParams lp = mLayoutParams; lp.x += deltaX; lp.y += deltaY; + lp.width = mBitmap.getWidth(); + lp.height = mBitmap.getHeight(); mDragLayer.requestLayout(); } } }); - mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true); + mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height); setDragRegion(new Rect(0, 0, width, height)); // The point in our scaled bitmap that the touch events are located @@ -208,6 +208,18 @@ public class DragView extends View { mAnim.start(); } + public void cancelAnimation() { + if (mAnim != null && mAnim.isRunning()) { + mAnim.cancel(); + } + } + + public void resetLayoutParams() { + DragLayer.LayoutParams lp = mLayoutParams; + lp.x = lp.y = 0; + mOffsetX = mOffsetY = 0; + } + /** * Move the window containing this view. * @@ -222,7 +234,9 @@ public class DragView extends View { } void remove() { - mDragLayer.removeView(DragView.this); + if (getParent() != null) { + mDragLayer.removeView(DragView.this); + } } int[] getPosition(int[] result) { diff --git a/src/com/android/launcher2/DropTarget.java b/src/com/android/launcher2/DropTarget.java index 4172da243..e49f7829b 100644 --- a/src/com/android/launcher2/DropTarget.java +++ b/src/com/android/launcher2/DropTarget.java @@ -55,6 +55,9 @@ public interface DropTarget { /** Indicates that the drag operation was cancelled */ public boolean cancelled = false; + /** Defers removing the DragView from the DragLayer until after the drop animation. */ + public boolean deferDragViewCleanupPostAnimation = true; + public DragObject() { } } diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java index 2a711f88b..a02351630 100644 --- a/src/com/android/launcher2/FolderIcon.java +++ b/src/com/android/launcher2/FolderIcon.java @@ -295,14 +295,14 @@ public class FolderIcon extends LinearLayout implements FolderListener { } public void performCreateAnimation(final ShortcutInfo destInfo, final View destView, - final ShortcutInfo srcInfo, final View srcView, Rect dstRect, + final ShortcutInfo srcInfo, final DragView srcView, Rect dstRect, float scaleRelativeToDragLayer, Runnable postAnimationRunnable) { Drawable animateDrawable = ((TextView) destView).getCompoundDrawables()[1]; computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), destView.getMeasuredWidth()); // This will animate the dragView (srcView) into the new folder - onDrop(srcInfo, srcView, dstRect, scaleRelativeToDragLayer, 1, postAnimationRunnable); + onDrop(srcInfo, srcView, dstRect, scaleRelativeToDragLayer, 1, postAnimationRunnable, null); // This will animate the first item from it's position as an icon into its // position as the first item in the preview @@ -320,8 +320,9 @@ public class FolderIcon extends LinearLayout implements FolderListener { mFolderRingAnimator.animateToNaturalState(); } - private void onDrop(final ShortcutInfo item, View animateView, Rect finalRect, - float scaleRelativeToDragLayer, int index, Runnable postAnimationRunnable) { + private void onDrop(final ShortcutInfo item, DragView animateView, Rect finalRect, + float scaleRelativeToDragLayer, int index, Runnable postAnimationRunnable, + DragObject d) { item.cellX = -1; item.cellY = -1; @@ -382,7 +383,7 @@ public class FolderIcon extends LinearLayout implements FolderListener { item = (ShortcutInfo) d.dragInfo; } mFolder.notifyDrop(); - onDrop(item, d.dragView, null, 1.0f, mInfo.contents.size(), d.postAnimationRunnable); + onDrop(item, d.dragView, null, 1.0f, mInfo.contents.size(), d.postAnimationRunnable, d); } public DropTarget getDropTargetDelegate(DragObject d) { diff --git a/src/com/android/launcher2/InfoDropTarget.java b/src/com/android/launcher2/InfoDropTarget.java index dba845b04..21fe8baca 100644 --- a/src/com/android/launcher2/InfoDropTarget.java +++ b/src/com/android/launcher2/InfoDropTarget.java @@ -29,6 +29,7 @@ import android.view.View; import android.view.ViewGroup; import com.android.launcher.R; +import com.android.launcher2.DropTarget.DragObject; public class InfoDropTarget extends ButtonDropTarget { @@ -85,6 +86,9 @@ public class InfoDropTarget extends ButtonDropTarget { if (componentName != null) { mLauncher.startApplicationDetailsActivity(componentName); } + + // There is no post-drop animation, so clean up the DragView now + d.deferDragViewCleanupPostAnimation = false; return false; } diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 746c68229..41a2bfb0f 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -169,7 +169,6 @@ public class Workspace extends SmoothPagedView private Bitmap mDragOutline = null; private final Rect mTempRect = new Rect(); private final int[] mTempXY = new int[2]; - private int mDragViewMultiplyColor; private float mOverscrollFade = 0; // Paint used to draw external drop outline @@ -291,7 +290,6 @@ public class Workspace extends SmoothPagedView mSpringLoadedShrinkFactor = res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f; - mDragViewMultiplyColor = res.getColor(R.color.drag_view_multiply_color); // if the value is manually specified, use that instead cellCountX = a.getInt(R.styleable.Workspace_cellCountX, cellCountX); @@ -1794,7 +1792,6 @@ public class Workspace extends SmoothPagedView canvas.setBitmap(b); drawDragView(v, canvas, padding, true); mOutlineHelper.applyOuterBlur(b, canvas, outlineColor); - canvas.drawColor(mDragViewMultiplyColor, PorterDuff.Mode.MULTIPLY); canvas.setBitmap(null); return b; @@ -2247,6 +2244,7 @@ public class Workspace extends SmoothPagedView mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, cell, duration, disableHardwareLayersRunnable, this); } else { + d.deferDragViewCleanupPostAnimation = false; cell.setVisibility(VISIBLE); } parent.onDropChild(cell); -- cgit v1.2.3