Changed folder hover animations
-> Added outer ring to hover animation
-> Fixed location of items in folder during hover animation
-> Cleaned up the code
Change-Id: I57c5f3cadbd2f289a18f7420a57ced6053fb06db
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index aa7d079..31c5ea0 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -45,11 +45,22 @@
private static final int NUM_ITEMS_IN_PREVIEW = 4;
private static final float ICON_ANGLE = 15f;
+ private static final int CONSUMPTION_ANIMATION_DURATION = 60;
+ private static final float INNER_RING_GROWTH_FACTOR = 0.1f;
+ private static final float OUTER_RING_BASELINE_SCALE = 0.7f;
+ private static final float OUTER_RING_GROWTH_FACTOR = 0.3f;
- int mOriginalWidth;
- int mOriginalHeight;
- int mOriginalX;
- int mOriginalY;
+ public static Drawable sFolderOuterRingDrawable = null;
+
+ private int mOriginalWidth = -1;
+ private int mOriginalHeight = -1;
+ private int mOriginalX = -1;
+ private int mOriginalY = -1;
+ private boolean mIsAnimating = false;
+
+ private int mFolderLocX;
+ private int mFolderLocY;
+ private float mOuterRingScale;
public FolderIcon(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -87,17 +98,25 @@
icon.mFolder = folder;
folderInfo.addListener(icon);
+ if (sFolderOuterRingDrawable == null) {
+ sFolderOuterRingDrawable =
+ launcher.getResources().getDrawable(R.drawable.portal_ring_outer_holo);
+ }
return icon;
}
+ private boolean willAcceptItem(ItemInfo item) {
+ final int itemType = item.itemType;
+ return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+ itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) &&
+ !mFolder.isFull() && item != mInfo);
+ }
+
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo;
- final int itemType = item.itemType;
- return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
- itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) &&
- !mFolder.isFull());
+ return willAcceptItem(item);
}
public void addItem(ShortcutInfo item) {
@@ -126,55 +145,112 @@
mOriginalY = lp.y;
}
- public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
+ private void animateToAcceptState() {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+
lp.isLockedToGrid = false;
saveState(lp);
- PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", (int) (1.1 * lp.width));
- PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", (int) (1.1 * lp.height));
- PropertyValuesHolder newX = PropertyValuesHolder.ofInt("x", lp.x - (int) (0.05 * lp.width));
- PropertyValuesHolder newY = PropertyValuesHolder.ofInt("y", lp.y - (int) (0.05 * lp.height));
- ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, newX, newY);
+ int newWidth = (int) ((1 + INNER_RING_GROWTH_FACTOR) * lp.width);
+ int newHeight = (int) ((1 + INNER_RING_GROWTH_FACTOR) * lp.width);
+ int newX = lp.x - (int) ((INNER_RING_GROWTH_FACTOR / 2) * lp.width);
+ int newY = lp.y - (int) ((INNER_RING_GROWTH_FACTOR / 2) * lp.height);
+ PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", newWidth);
+ PropertyValuesHolder height = PropertyValuesHolder.ofInt("height",newHeight);
+ PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", newX);
+ PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", newY);
+ ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
+ oa.setDuration(CONSUMPTION_ANIMATION_DURATION);
oa.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
- invalidate();
requestLayout();
+ invalidate();
}
});
- oa.setDuration(50);
+ oa.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mIsAnimating = true;
+ }
+ });
+ ValueAnimator outerRingScale = ValueAnimator.ofFloat(0f, 1f);
+ outerRingScale.setDuration(CONSUMPTION_ANIMATION_DURATION);
+ outerRingScale.addUpdateListener(new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final float percent = (Float) animation.getAnimatedValue();
+ mOuterRingScale = OUTER_RING_BASELINE_SCALE + percent * OUTER_RING_GROWTH_FACTOR;
+ mLauncher.getWorkspace().invalidate();
+ }
+ });
+
+ outerRingScale.start();
oa.start();
}
+ private void animateToNaturalState() {
+ final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+ lp.isLockedToGrid = false;
+
+ PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", mOriginalWidth);
+ PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", mOriginalHeight);
+ PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", mOriginalX);
+ PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", mOriginalY);
+ ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
+ oa.addUpdateListener(new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ requestLayout();
+ invalidate();
+ }
+ });
+ oa.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ lp.isLockedToGrid = true;
+ mIsAnimating = false;
+ }
+ });
+
+ ValueAnimator outerRingScale = ValueAnimator.ofFloat(0f, 1f);
+ outerRingScale.setDuration(CONSUMPTION_ANIMATION_DURATION);
+ outerRingScale.addUpdateListener(new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final float percent = (Float) animation.getAnimatedValue();
+ mOuterRingScale = OUTER_RING_BASELINE_SCALE + OUTER_RING_GROWTH_FACTOR
+ - percent * OUTER_RING_GROWTH_FACTOR;
+ mLauncher.getWorkspace().invalidate();
+ }
+ });
+
+ oa.setDuration(CONSUMPTION_ANIMATION_DURATION);
+ oa.start();
+ }
+
+ private void determineFolderLocationInWorkspace() {
+ int tvLocation[] = new int[2];
+ int wsLocation[] = new int[2];
+ getLocationOnScreen(tvLocation);
+ mLauncher.getWorkspace().getLocationOnScreen(wsLocation);
+ mFolderLocX = tvLocation[0] - wsLocation[0] + getMeasuredWidth() / 2;
+ mFolderLocY = tvLocation[1] - wsLocation[1] + getMeasuredHeight() / 2;
+ }
+
+ public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
+ DragView dragView, Object dragInfo) {
+ if (!willAcceptItem((ItemInfo) dragInfo)) return;
+ determineFolderLocationInWorkspace();
+ mLauncher.getWorkspace().showFolderAccept(this);
+ animateToAcceptState();
+ }
+
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
}
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
- final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
- lp.isLockedToGrid = false;
-
- PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", mOriginalWidth);
- PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", mOriginalHeight);
- PropertyValuesHolder newX = PropertyValuesHolder.ofInt("x", mOriginalX);
- PropertyValuesHolder newY = PropertyValuesHolder.ofInt("y", mOriginalY);
- ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, newX, newY);
- oa.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
- invalidate();
- requestLayout();
- }
- });
- oa.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- lp.isLockedToGrid = true;
- }
- });
- oa.setDuration(50);
- oa.start();
+ if (!willAcceptItem((ItemInfo) dragInfo)) return;
+ mLauncher.getWorkspace().hideFolderAccept(this);
+ animateToNaturalState();
}
@Override
@@ -183,6 +259,15 @@
return null;
}
+ public void getFolderLocation(int[] loc) {
+ loc[0] = mFolderLocX;
+ loc[1] = mFolderLocY;
+ }
+
+ public float getOuterRingScale() {
+ return mOuterRingScale;
+ }
+
@Override
protected void onDraw(Canvas canvas) {
if (mFolder == null) return;
@@ -192,12 +277,23 @@
TextView v = (TextView) mFolder.getItemAt(0);
Drawable d = v.getCompoundDrawables()[1];
- canvas.translate( (getMeasuredWidth() - d.getIntrinsicWidth()) / 2,
- (getMeasuredHeight() - d.getIntrinsicHeight()) / 2);
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+ if (mOriginalWidth < 0 || mOriginalHeight < 0) {
+ mOriginalWidth = getMeasuredWidth();
+ mOriginalHeight = getMeasuredHeight();
+ }
+ int xShift = (mOriginalWidth - d.getIntrinsicWidth()) / 2;
+ int yShift = (mOriginalHeight - d.getIntrinsicHeight()) / 2;
+
+ if (mIsAnimating) {
+ xShift -= lp.x - mOriginalX;
+ yShift -= lp.y - mOriginalY;
+ }
+
+ canvas.translate(xShift, yShift);
canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2);
canvas.rotate(ICON_ANGLE);
-
canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2);
for (int i = Math.max(0, mFolder.getItemCount() - NUM_ITEMS_IN_PREVIEW);
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 24160f0..fed991c 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -161,6 +161,7 @@
private float[] mTempCellLayoutCenterCoordinates = new float[2];
private float[] mTempDragBottomRightCoordinates = new float[2];
private Matrix mTempInverseMatrix = new Matrix();
+ private int[] mTempLocation = new int[2];
private SpringLoadedDragController mSpringLoadedDragController;
@@ -222,6 +223,8 @@
private int mLastDragXOffset;
private int mLastDragYOffset;
+ private ArrayList<FolderIcon> mFolderOuterRings = new ArrayList<FolderIcon>();
+
// Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
private float mXDown;
private float mYDown;
@@ -1185,6 +1188,16 @@
}
}
+ public void showFolderAccept(FolderIcon fi) {
+ mFolderOuterRings.add(fi);
+ }
+
+ public void hideFolderAccept(FolderIcon fi) {
+ if (mFolderOuterRings.contains(fi)) {
+ mFolderOuterRings.remove(fi);
+ }
+ }
+
@Override
protected void onDraw(Canvas canvas) {
updateWallpaperOffsets();
@@ -1220,6 +1233,19 @@
mBackground.draw(canvas);
}
}
+
+ // The folder outer ring image(s)
+ for (int i = 0; i < mFolderOuterRings.size(); i++) {
+ FolderIcon fi = mFolderOuterRings.get(i);
+ final Drawable d = FolderIcon.sFolderOuterRingDrawable;
+ final int width = (int) (d.getIntrinsicWidth() * fi.getOuterRingScale());
+ final int height = (int) (d.getIntrinsicHeight() * fi.getOuterRingScale());
+ fi.getFolderLocation(mTempLocation);
+ final int x = mTempLocation[0] + mScrollX - width / 2;
+ final int y = mTempLocation[1] + mScrollY - height / 2;
+ d.setBounds(x, y, x + width, y + height);
+ d.draw(canvas);
+ }
super.onDraw(canvas);
}