Add new motion for when Folder preview changes due to onDrop. am: 4dd024b974
Change-Id: I2890d07784fdf4e7530e840434293bf5cdb80b4e
This commit is contained in:
@@ -1,15 +1,18 @@
|
||||
package com.android.launcher3.folder;
|
||||
|
||||
|
||||
public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
|
||||
|
||||
static final int MAX_NUM_ITEMS_IN_PREVIEW = 4;
|
||||
private static final int MIN_NUM_ITEMS_IN_PREVIEW = 2;
|
||||
private static final int MAX_NUM_ITEMS_PER_ROW = 2;
|
||||
|
||||
final float MIN_SCALE = 0.48f;
|
||||
final float MAX_SCALE = 0.58f;
|
||||
final float MAX_RADIUS_DILATION = 0.15f;
|
||||
final float ITEM_RADIUS_SCALE_FACTOR = 1.33f;
|
||||
private static final float MIN_SCALE = 0.48f;
|
||||
private static final float MAX_SCALE = 0.58f;
|
||||
private static final float MAX_RADIUS_DILATION = 0.15f;
|
||||
private static final float ITEM_RADIUS_SCALE_FACTOR = 1.33f;
|
||||
|
||||
private static final int EXIT_INDEX = -2;
|
||||
private static final int ENTER_INDEX = -3;
|
||||
|
||||
private float[] mTmpPoint = new float[2];
|
||||
|
||||
@@ -31,21 +34,29 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule
|
||||
@Override
|
||||
public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
|
||||
PreviewItemDrawingParams params) {
|
||||
|
||||
float totalScale = scaleForItem(index, curNumItems);
|
||||
float transX;
|
||||
float transY;
|
||||
float overlayAlpha = 0;
|
||||
|
||||
// Items beyond those displayed in the preview are animated to the center
|
||||
if (index >= MAX_NUM_ITEMS_IN_PREVIEW) {
|
||||
transX = transY = mAvailableSpace / 2 - (mIconSize * totalScale) / 2;
|
||||
if (index == getExitIndex()) {
|
||||
// 0 1 * <-- Exit position (row 0, col 2)
|
||||
// 2 3
|
||||
getGridPosition(0, 2, mTmpPoint);
|
||||
} else if (index == getEnterIndex()) {
|
||||
// 0 1
|
||||
// 2 3 * <-- Enter position (row 1, col 2)
|
||||
getGridPosition(1, 2, mTmpPoint);
|
||||
} else if (index >= MAX_NUM_ITEMS_IN_PREVIEW) {
|
||||
// Items beyond those displayed in the preview are animated to the center
|
||||
mTmpPoint[0] = mTmpPoint[1] = mAvailableSpace / 2 - (mIconSize * totalScale) / 2;
|
||||
} else {
|
||||
getPosition(index, curNumItems, mTmpPoint);
|
||||
transX = mTmpPoint[0];
|
||||
transY = mTmpPoint[1];
|
||||
}
|
||||
|
||||
transX = mTmpPoint[0];
|
||||
transY = mTmpPoint[1];
|
||||
|
||||
if (params == null) {
|
||||
params = new PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha);
|
||||
} else {
|
||||
@@ -55,6 +66,27 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a grid based on the positioning of the items when there are
|
||||
* {@link #MAX_NUM_ITEMS_IN_PREVIEW} in the preview.
|
||||
*
|
||||
* Positions in the grid: 0 1 // 0 is row 0, col 1
|
||||
* 2 3 // 3 is row 1, col 1
|
||||
*/
|
||||
private void getGridPosition(int row, int col, float[] result) {
|
||||
// We use position 0 and 3 to calculate the x and y distances between items.
|
||||
getPosition(0, 4, result);
|
||||
float left = result[0];
|
||||
float top = result[1];
|
||||
|
||||
getPosition(3, 4, result);
|
||||
float dx = result[0] - left;
|
||||
float dy = result[1] - top;
|
||||
|
||||
result[0] = left + (col * dx);
|
||||
result[1] = top + (row * dy);
|
||||
}
|
||||
|
||||
private void getPosition(int index, int curNumItems, float[] result) {
|
||||
// The case of two items is homomorphic to the case of one.
|
||||
curNumItems = Math.max(curNumItems, 2);
|
||||
@@ -127,4 +159,19 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule
|
||||
public boolean clipToBackground() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnterExitIndices() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExitIndex() {
|
||||
return EXIT_INDEX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnterIndex() {
|
||||
return ENTER_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,15 @@ public class FolderIcon extends FrameLayout implements FolderListener {
|
||||
}
|
||||
|
||||
public void addItem(ShortcutInfo item) {
|
||||
mInfo.add(item, true);
|
||||
addItem(item, true);
|
||||
}
|
||||
|
||||
public void addItem(ShortcutInfo item, boolean animate) {
|
||||
mInfo.add(item, animate);
|
||||
}
|
||||
|
||||
public void removeItem(ShortcutInfo item, boolean animate) {
|
||||
mInfo.remove(item, animate);
|
||||
}
|
||||
|
||||
public void onDragEnter(ItemInfo dragInfo) {
|
||||
@@ -276,7 +284,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
|
||||
}
|
||||
|
||||
private void onDrop(final ShortcutInfo item, DragView animateView, Rect finalRect,
|
||||
float scaleRelativeToDragLayer, final int index, Runnable postAnimationRunnable) {
|
||||
float scaleRelativeToDragLayer, int index, Runnable postAnimationRunnable) {
|
||||
item.cellX = -1;
|
||||
item.cellY = -1;
|
||||
|
||||
@@ -304,13 +312,39 @@ public class FolderIcon extends FrameLayout implements FolderListener {
|
||||
workspace.resetTransitionTransform((CellLayout) getParent().getParent());
|
||||
}
|
||||
|
||||
boolean itemAdded = false;
|
||||
if (index >= mPreviewLayoutRule.maxNumItems()
|
||||
&& mPreviewLayoutRule.hasEnterExitIndices()) {
|
||||
List<BubbleTextView> oldPreviewItems = getPreviewItemsOnPage(0);
|
||||
addItem(item, false);
|
||||
List<BubbleTextView> newPreviewItems = getPreviewItemsOnPage(0);
|
||||
|
||||
if (!oldPreviewItems.containsAll(newPreviewItems)) {
|
||||
for (int i = 0; i < newPreviewItems.size(); ++i) {
|
||||
if (newPreviewItems.get(i).getTag().equals(item)) {
|
||||
// If the item dropped is going to be in the preview, we update the
|
||||
// index here to reflect its position in the preview.
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
mPreviewItemManager.onDrop(oldPreviewItems, newPreviewItems, item);
|
||||
itemAdded = true;
|
||||
} else {
|
||||
removeItem(item, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!itemAdded) {
|
||||
addItem(item);
|
||||
}
|
||||
|
||||
int[] center = new int[2];
|
||||
float scale = getLocalCenterForIndex(index, index + 1, center);
|
||||
center[0] = (int) Math.round(scaleRelativeToDragLayer * center[0]);
|
||||
center[1] = (int) Math.round(scaleRelativeToDragLayer * center[1]);
|
||||
|
||||
to.offset(center[0] - animateView.getMeasuredWidth() / 2,
|
||||
center[1] - animateView.getMeasuredHeight() / 2);
|
||||
center[1] - animateView.getMeasuredHeight() / 2);
|
||||
|
||||
float finalAlpha = index < mPreviewLayoutRule.maxNumItems() ? 0.5f : 0f;
|
||||
|
||||
@@ -319,13 +353,14 @@ public class FolderIcon extends FrameLayout implements FolderListener {
|
||||
1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION,
|
||||
new DecelerateInterpolator(2), new AccelerateInterpolator(2),
|
||||
postAnimationRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null);
|
||||
addItem(item);
|
||||
|
||||
mFolder.hideItem(item);
|
||||
|
||||
mPreviewItemManager.hidePreviewItem(index, true);
|
||||
if (!itemAdded) mPreviewItemManager.hidePreviewItem(index, true);
|
||||
final int finalIndex = index;
|
||||
postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
mPreviewItemManager.hidePreviewItem(index, false);
|
||||
mPreviewItemManager.hidePreviewItem(finalIndex, false);
|
||||
mFolder.showItem(item);
|
||||
invalidate();
|
||||
}
|
||||
@@ -655,11 +690,16 @@ public class FolderIcon extends FrameLayout implements FolderListener {
|
||||
|
||||
interface PreviewLayoutRule {
|
||||
PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
|
||||
PreviewItemDrawingParams params);
|
||||
PreviewItemDrawingParams params);
|
||||
void init(int availableSpace, float intrinsicIconSize, boolean rtl);
|
||||
float scaleForItem(int index, int totalNumItems);
|
||||
float getIconSize();
|
||||
int maxNumItems();
|
||||
boolean clipToBackground();
|
||||
|
||||
boolean hasEnterExitIndices();
|
||||
int getExitIndex();
|
||||
int getEnterIndex();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,19 +40,14 @@ public class FolderIconPreviewVerifier {
|
||||
}
|
||||
|
||||
public void setFolderInfo(FolderInfo info) {
|
||||
FolderPagedView.calculateGridSize(info.contents.size(), 0, 0, mMaxGridCountX,
|
||||
int numItemsInFolder = info.contents.size();
|
||||
FolderPagedView.calculateGridSize(numItemsInFolder, 0, 0, mMaxGridCountX,
|
||||
mMaxGridCountY, mMaxItemsPerPage, mGridSize);
|
||||
mGridCountX = mGridSize[0];
|
||||
int numItemsInFolder = info.contents.size();
|
||||
|
||||
mDisplayingUpperLeftQuadrant = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION
|
||||
&& !FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON
|
||||
&& numItemsInFolder > FolderIcon.NUM_ITEMS_IN_PREVIEW;
|
||||
|
||||
if (mDisplayingUpperLeftQuadrant) {
|
||||
FolderPagedView.calculateGridSize(info.contents.size(), 0, 0, mMaxGridCountX,
|
||||
mMaxGridCountY, mMaxItemsPerPage, mGridSize);
|
||||
mGridCountX = mGridSize[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.ShortcutInfo;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
|
||||
@@ -273,4 +274,80 @@ public class PreviewItemManager {
|
||||
float getIntrinsicIconSize() {
|
||||
return mIntrinsicIconSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the case where items in the preview are either:
|
||||
* - Moving into the preview
|
||||
* - Moving into a new position
|
||||
* - Moving out of the preview
|
||||
*
|
||||
* @param oldParams The list of items in the old preview.
|
||||
* @param newParams The list of items in the new preview.
|
||||
* @param dropped The item that was dropped onto the FolderIcon.
|
||||
*/
|
||||
public void onDrop(List<BubbleTextView> oldParams, List<BubbleTextView> newParams,
|
||||
ShortcutInfo dropped) {
|
||||
int numItems = newParams.size();
|
||||
final ArrayList<PreviewItemDrawingParams> params = mFirstPageParams;
|
||||
buildParamsForPage(0, params, false);
|
||||
|
||||
// New preview items for items that are moving in (except for the dropped item).
|
||||
List<BubbleTextView> moveIn = new ArrayList<>();
|
||||
for (BubbleTextView btv : newParams) {
|
||||
if (!oldParams.contains(btv) && !btv.getTag().equals(dropped)) {
|
||||
moveIn.add(btv);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < moveIn.size(); ++i) {
|
||||
int prevIndex = newParams.indexOf(moveIn.get(i));
|
||||
PreviewItemDrawingParams p = params.get(prevIndex);
|
||||
computePreviewItemDrawingParams(prevIndex, numItems, p);
|
||||
updateTransitionParam(p, moveIn.get(i), mIcon.mPreviewLayoutRule.getEnterIndex(),
|
||||
newParams.indexOf(moveIn.get(i)));
|
||||
}
|
||||
|
||||
// Items that are moving into new positions within the preview.
|
||||
for (int newIndex = 0; newIndex < newParams.size(); ++newIndex) {
|
||||
int oldIndex = oldParams.indexOf(newParams.get(newIndex));
|
||||
if (oldIndex >= 0 && newIndex != oldIndex) {
|
||||
PreviewItemDrawingParams p = params.get(newIndex);
|
||||
updateTransitionParam(p, newParams.get(newIndex), oldIndex, newIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Old preview items that need to be moved out.
|
||||
List<BubbleTextView> moveOut = new ArrayList<>(oldParams);
|
||||
moveOut.removeAll(newParams);
|
||||
for (int i = 0; i < moveOut.size(); ++i) {
|
||||
BubbleTextView item = moveOut.get(i);
|
||||
int oldIndex = oldParams.indexOf(item);
|
||||
PreviewItemDrawingParams p = computePreviewItemDrawingParams(oldIndex, numItems, null);
|
||||
updateTransitionParam(p, item, oldIndex, mIcon.mPreviewLayoutRule.getExitIndex());
|
||||
params.add(0, p); // We want these items first so that they are on drawn last.
|
||||
}
|
||||
|
||||
for (int i = 0; i < params.size(); ++i) {
|
||||
if (params.get(i).anim != null) {
|
||||
params.get(i).anim.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTransitionParam(final PreviewItemDrawingParams p, BubbleTextView btv,
|
||||
int prevIndex, int newIndex) {
|
||||
p.drawable = btv.getCompoundDrawables()[1];
|
||||
if (!mIcon.mFolder.isOpen()) {
|
||||
// Set the callback to FolderIcon as it is responsible to drawing the icon. The
|
||||
// callback will be released when the folder is opened.
|
||||
p.drawable.setCallback(mIcon);
|
||||
}
|
||||
|
||||
FolderPreviewItemAnim anim = new FolderPreviewItemAnim(this, p, prevIndex,
|
||||
FolderIcon.NUM_ITEMS_IN_PREVIEW, newIndex, FolderIcon.NUM_ITEMS_IN_PREVIEW,
|
||||
DROP_IN_ANIMATION_DURATION, null);
|
||||
if (p.anim != null && !p.anim.hasEqualFinalState(anim)) {
|
||||
p.anim.cancel();
|
||||
}
|
||||
p.anim = anim;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,4 +97,19 @@ public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
|
||||
public boolean clipToBackground() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnterExitIndices() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExitIndex() {
|
||||
throw new RuntimeException("hasEnterExitIndices not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnterIndex() {
|
||||
throw new RuntimeException("hasEnterExitIndices not supported");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user