Merge "Adding animation when destroying folder due to single item remaining"
This commit is contained in:
committed by
Android (Google) Code Review
commit
e783cde98d
@@ -108,6 +108,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
private static String sHintText;
|
||||
private ObjectAnimator mOpenCloseAnimator;
|
||||
|
||||
private boolean mDestroyed;
|
||||
|
||||
/**
|
||||
* Used to inflate the Workspace from XML.
|
||||
*
|
||||
@@ -941,34 +943,45 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
}
|
||||
|
||||
private void replaceFolderWithFinalItem() {
|
||||
ItemInfo finalItem = null;
|
||||
|
||||
if (getItemCount() == 1) {
|
||||
finalItem = mInfo.contents.get(0);
|
||||
}
|
||||
|
||||
// Remove the folder completely
|
||||
CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screen);
|
||||
cellLayout.removeView(mFolderIcon);
|
||||
if (mFolderIcon instanceof DropTarget) {
|
||||
mDragController.removeDropTarget((DropTarget) mFolderIcon);
|
||||
}
|
||||
mLauncher.removeFolder(mInfo);
|
||||
|
||||
if (finalItem != null) {
|
||||
LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container,
|
||||
mInfo.screen, mInfo.cellX, mInfo.cellY);
|
||||
}
|
||||
LauncherModel.deleteItemFromDatabase(mLauncher, mInfo);
|
||||
|
||||
// Add the last remaining child to the workspace in place of the folder
|
||||
if (finalItem != null) {
|
||||
View child = mLauncher.createShortcut(R.layout.application, cellLayout,
|
||||
(ShortcutInfo) finalItem);
|
||||
Runnable onCompleteRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screen);
|
||||
|
||||
mLauncher.getWorkspace().addInScreen(child, mInfo.container, mInfo.screen, mInfo.cellX,
|
||||
mInfo.cellY, mInfo.spanX, mInfo.spanY);
|
||||
if (getItemCount() <= 1) {
|
||||
// Remove the folder
|
||||
LauncherModel.deleteItemFromDatabase(mLauncher, mInfo);
|
||||
cellLayout.removeView(mFolderIcon);
|
||||
if (mFolderIcon instanceof DropTarget) {
|
||||
mDragController.removeDropTarget((DropTarget) mFolderIcon);
|
||||
}
|
||||
mLauncher.removeFolder(mInfo);
|
||||
}
|
||||
|
||||
// Move the item from the folder to the workspace, in the position of the folder
|
||||
if (getItemCount() == 1) {
|
||||
ShortcutInfo finalItem = mInfo.contents.get(0);
|
||||
|
||||
final View child = mLauncher.createShortcut(R.layout.application, cellLayout,
|
||||
finalItem);
|
||||
LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container,
|
||||
mInfo.screen, mInfo.cellX, mInfo.cellY);
|
||||
mLauncher.getWorkspace().addInScreen(child, mInfo.container, mInfo.screen,
|
||||
mInfo.cellX, mInfo.cellY, mInfo.spanX, mInfo.spanY);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
View finalChild = getItemAt(0);
|
||||
if (finalChild != null) {
|
||||
mFolderIcon.performDestroyAnimation(finalChild, onCompleteRunnable);
|
||||
}
|
||||
mDestroyed = true;
|
||||
}
|
||||
|
||||
boolean isDestroyed() {
|
||||
return mDestroyed;
|
||||
}
|
||||
|
||||
// This method keeps track of the last item in the folder for the purposes
|
||||
|
||||
@@ -50,8 +50,8 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
private Launcher mLauncher;
|
||||
Folder mFolder;
|
||||
FolderInfo mInfo;
|
||||
private Folder mFolder;
|
||||
private FolderInfo mInfo;
|
||||
private static boolean sStaticValuesDirty = true;
|
||||
|
||||
private CheckLongPressHelper mLongPressHelper;
|
||||
@@ -61,6 +61,7 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
private static final int CONSUMPTION_ANIMATION_DURATION = 100;
|
||||
private static final int DROP_IN_ANIMATION_DURATION = 400;
|
||||
private static final int INITIAL_ITEM_ANIMATION_DURATION = 350;
|
||||
private static final int FINAL_ITEM_ANIMATION_DURATION = 200;
|
||||
|
||||
// The degree to which the inner ring grows when accepting drop
|
||||
private static final float INNER_RING_GROWTH_FACTOR = 0.15f;
|
||||
@@ -93,8 +94,10 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
private int mPreviewOffsetY;
|
||||
private float mMaxPerspectiveShift;
|
||||
boolean mAnimating = false;
|
||||
|
||||
private PreviewItemDrawingParams mParams = new PreviewItemDrawingParams(0, 0, 0, 0);
|
||||
private PreviewItemDrawingParams mAnimParams = new PreviewItemDrawingParams(0, 0, 0, 0);
|
||||
private ArrayList<ShortcutInfo> mHiddenItems = new ArrayList<ShortcutInfo>();
|
||||
|
||||
public FolderIcon(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -278,6 +281,14 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
}
|
||||
}
|
||||
|
||||
Folder getFolder() {
|
||||
return mFolder;
|
||||
}
|
||||
|
||||
FolderInfo getFolderInfo() {
|
||||
return mInfo;
|
||||
}
|
||||
|
||||
private boolean willAcceptItem(ItemInfo item) {
|
||||
final int itemType = item.itemType;
|
||||
return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
|
||||
@@ -287,7 +298,7 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
|
||||
public boolean acceptDrop(Object dragInfo) {
|
||||
final ItemInfo item = (ItemInfo) dragInfo;
|
||||
return willAcceptItem(item);
|
||||
return !mFolder.isDestroyed() && willAcceptItem(item);
|
||||
}
|
||||
|
||||
public void addItem(ShortcutInfo item) {
|
||||
@@ -296,7 +307,7 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
}
|
||||
|
||||
public void onDragEnter(Object dragInfo) {
|
||||
if (!willAcceptItem((ItemInfo) dragInfo)) return;
|
||||
if (mFolder.isDestroyed() || !willAcceptItem((ItemInfo) dragInfo)) return;
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
|
||||
CellLayout layout = (CellLayout) getParent().getParent();
|
||||
mFolderRingAnimator.setCell(lp.cellX, lp.cellY);
|
||||
@@ -312,16 +323,29 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
final ShortcutInfo srcInfo, final DragView srcView, Rect dstRect,
|
||||
float scaleRelativeToDragLayer, Runnable postAnimationRunnable) {
|
||||
|
||||
// These correspond two the drawable and view that the icon was dropped _onto_
|
||||
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, null);
|
||||
computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(),
|
||||
destView.getMeasuredWidth());
|
||||
|
||||
// This will animate the first item from it's position as an icon into its
|
||||
// position as the first item in the preview
|
||||
animateFirstItem(animateDrawable, INITIAL_ITEM_ANIMATION_DURATION);
|
||||
animateFirstItem(animateDrawable, INITIAL_ITEM_ANIMATION_DURATION, false, null);
|
||||
addItem(destInfo);
|
||||
|
||||
// This will animate the dragView (srcView) into the new folder
|
||||
onDrop(srcInfo, srcView, dstRect, scaleRelativeToDragLayer, 1, postAnimationRunnable, null);
|
||||
}
|
||||
|
||||
public void performDestroyAnimation(final View finalView, Runnable onCompleteRunnable) {
|
||||
Drawable animateDrawable = ((TextView) finalView).getCompoundDrawables()[1];
|
||||
computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(),
|
||||
finalView.getMeasuredWidth());
|
||||
|
||||
// This will animate the first item from it's position as an icon into its
|
||||
// position as the first item in the preview
|
||||
animateFirstItem(animateDrawable, FINAL_ITEM_ANIMATION_DURATION, true,
|
||||
onCompleteRunnable);
|
||||
}
|
||||
|
||||
public void onDragExit(Object dragInfo) {
|
||||
@@ -377,9 +401,12 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION,
|
||||
new DecelerateInterpolator(2), new AccelerateInterpolator(2),
|
||||
postAnimationRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null);
|
||||
addItem(item);
|
||||
mHiddenItems.add(item);
|
||||
postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
addItem(item);
|
||||
mHiddenItems.remove(item);
|
||||
invalidate();
|
||||
}
|
||||
}, DROP_IN_ANIMATION_DURATION);
|
||||
} else {
|
||||
@@ -526,19 +553,20 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
if (!mAnimating) {
|
||||
for (int i = nItemsInPreview - 1; i >= 0; i--) {
|
||||
v = (TextView) items.get(i);
|
||||
d = v.getCompoundDrawables()[1];
|
||||
|
||||
mParams = computePreviewItemDrawingParams(i, mParams);
|
||||
mParams.drawable = d;
|
||||
drawPreviewItem(canvas, mParams);
|
||||
if (!mHiddenItems.contains(v.getTag())) {
|
||||
d = v.getCompoundDrawables()[1];
|
||||
mParams = computePreviewItemDrawingParams(i, mParams);
|
||||
mParams.drawable = d;
|
||||
drawPreviewItem(canvas, mParams);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
drawPreviewItem(canvas, mAnimParams);
|
||||
}
|
||||
}
|
||||
|
||||
private void animateFirstItem(final Drawable d, int duration) {
|
||||
computePreviewDrawingParams(d);
|
||||
private void animateFirstItem(final Drawable d, int duration, final boolean reverse,
|
||||
final Runnable onCompleteRunnable) {
|
||||
final PreviewItemDrawingParams finalParams = computePreviewItemDrawingParams(0, null);
|
||||
|
||||
final float scale0 = 1.0f;
|
||||
@@ -550,6 +578,10 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
va.addUpdateListener(new AnimatorUpdateListener(){
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
float progress = (Float) animation.getAnimatedValue();
|
||||
if (reverse) {
|
||||
progress = 1 - progress;
|
||||
mPreviewBackground.setAlpha(progress);
|
||||
}
|
||||
|
||||
mAnimParams.transX = transX0 + progress * (finalParams.transX - transX0);
|
||||
mAnimParams.transY = transY0 + progress * (finalParams.transY - transY0);
|
||||
@@ -565,6 +597,9 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mAnimating = false;
|
||||
if (onCompleteRunnable != null) {
|
||||
onCompleteRunnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
va.setDuration(duration);
|
||||
|
||||
@@ -2002,7 +2002,7 @@ public final class Launcher extends Activity
|
||||
}
|
||||
|
||||
private void handleFolderClick(FolderIcon folderIcon) {
|
||||
final FolderInfo info = folderIcon.mInfo;
|
||||
final FolderInfo info = folderIcon.getFolderInfo();
|
||||
Folder openFolder = mWorkspace.getFolderForTag(info);
|
||||
|
||||
// If the folder info reports that the associated folder is open, then verify that
|
||||
@@ -2013,7 +2013,7 @@ public final class Launcher extends Activity
|
||||
info.opened = false;
|
||||
}
|
||||
|
||||
if (!info.opened) {
|
||||
if (!info.opened && !folderIcon.getFolder().isDestroyed()) {
|
||||
// Close any open folder
|
||||
closeFolder();
|
||||
// Open the requested folder
|
||||
@@ -2070,9 +2070,9 @@ public final class Launcher extends Activity
|
||||
mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
|
||||
fi.draw(mFolderIconCanvas);
|
||||
mFolderIconImageView.setImageBitmap(mFolderIconBitmap);
|
||||
if (fi.mFolder != null) {
|
||||
mFolderIconImageView.setPivotX(fi.mFolder.getPivotXForIconAnimation());
|
||||
mFolderIconImageView.setPivotY(fi.mFolder.getPivotYForIconAnimation());
|
||||
if (fi.getFolder() != null) {
|
||||
mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());
|
||||
mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());
|
||||
}
|
||||
// Just in case this image view is still in the drag layer from a previous animation,
|
||||
// we remove it and re-add it.
|
||||
@@ -2080,8 +2080,8 @@ public final class Launcher extends Activity
|
||||
mDragLayer.removeView(mFolderIconImageView);
|
||||
}
|
||||
mDragLayer.addView(mFolderIconImageView, lp);
|
||||
if (fi.mFolder != null) {
|
||||
fi.mFolder.bringToFront();
|
||||
if (fi.getFolder() != null) {
|
||||
fi.getFolder().bringToFront();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2144,7 +2144,7 @@ public final class Launcher extends Activity
|
||||
* @param folderInfo The FolderInfo describing the folder to open.
|
||||
*/
|
||||
public void openFolder(FolderIcon folderIcon) {
|
||||
Folder folder = folderIcon.mFolder;
|
||||
Folder folder = folderIcon.getFolder();
|
||||
FolderInfo info = folder.mInfo;
|
||||
|
||||
info.opened = true;
|
||||
|
||||
Reference in New Issue
Block a user