Cleaning up Folder accept animation drawing
-> Moved from Workspace to CellLayout, which fixes a bunch of bugs with transforms (springloaded mode and page scrolling) Change-Id: I92510be817f46bd29b8a10aac5512dc1ead87180
This commit is contained in:
@@ -29,6 +29,7 @@ import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
@@ -47,7 +48,9 @@ import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LayoutAnimationController;
|
||||
|
||||
import com.android.launcher.R;
|
||||
import com.android.launcher2.FolderIcon.FolderRingAnimator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -74,11 +77,14 @@ public class CellLayout extends ViewGroup {
|
||||
private final int[] mTmpXY = new int[2];
|
||||
private final int[] mTmpPoint = new int[2];
|
||||
private final PointF mTmpPointF = new PointF();
|
||||
int[] mTempLocation = new int[2];
|
||||
|
||||
boolean[][] mOccupied;
|
||||
|
||||
private OnTouchListener mInterceptTouchListener;
|
||||
|
||||
private ArrayList<FolderRingAnimator> mFolderOuterRings = new ArrayList<FolderRingAnimator>();
|
||||
|
||||
private float mBackgroundAlpha;
|
||||
private float mBackgroundAlphaMultiplier = 1.0f;
|
||||
|
||||
@@ -516,6 +522,51 @@ public class CellLayout extends ViewGroup {
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
// The folder outer / inner ring image(s)
|
||||
for (int i = 0; i < mFolderOuterRings.size(); i++) {
|
||||
FolderRingAnimator fra = mFolderOuterRings.get(i);
|
||||
|
||||
// Draw outer ring
|
||||
Drawable d = FolderRingAnimator.sSharedOuterRingDrawable;
|
||||
int width = (int) fra.getOuterRingSize();
|
||||
int height = width;
|
||||
cellToPoint(fra.mCellX, fra.mCellY, mTempLocation);
|
||||
|
||||
int centerX = mTempLocation[0] + mCellWidth / 2;
|
||||
int centerY = mTempLocation[1] + FolderRingAnimator.sPreviewSize / 2;
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(centerX - width / 2, centerY - height / 2);
|
||||
d.setBounds(0, 0, width, height);
|
||||
d.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
// Draw inner ring
|
||||
d = FolderRingAnimator.sSharedInnerRingDrawable;
|
||||
width = (int) fra.getInnerRingSize();
|
||||
height = width;
|
||||
cellToPoint(fra.mCellX, fra.mCellY, mTempLocation);
|
||||
|
||||
centerX = mTempLocation[0] + mCellWidth / 2;
|
||||
centerY = mTempLocation[1] + FolderRingAnimator.sPreviewSize / 2;
|
||||
canvas.save();
|
||||
canvas.translate(centerX - width / 2, centerY - width / 2);
|
||||
d.setBounds(0, 0, width, height);
|
||||
d.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
public void showFolderAccept(FolderRingAnimator fra) {
|
||||
mFolderOuterRings.add(fra);
|
||||
}
|
||||
|
||||
public void hideFolderAccept(FolderRingAnimator fra) {
|
||||
if (mFolderOuterRings.contains(fra)) {
|
||||
mFolderOuterRings.remove(fra);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -83,7 +83,6 @@ public class CellLayoutChildren extends ViewGroup {
|
||||
lp.setup(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
|
||||
}
|
||||
|
||||
|
||||
public void measureChild(View child) {
|
||||
final int cellWidth = mCellWidth;
|
||||
final int cellHeight = mCellHeight;
|
||||
|
||||
@@ -56,10 +56,10 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
private static final int CONSUMPTION_ANIMATION_DURATION = 100;
|
||||
|
||||
// The degree to which the inner ring grows when accepting drop
|
||||
private static final float INNER_RING_GROWTH_FACTOR = 0.1f;
|
||||
private static final float INNER_RING_GROWTH_FACTOR = 0.15f;
|
||||
|
||||
// The degree to which the outer ring is scaled in its natural state
|
||||
private static final float OUTER_RING_GROWTH_FACTOR = 0.4f;
|
||||
private static final float OUTER_RING_GROWTH_FACTOR = 0.3f;
|
||||
|
||||
// The amount of vertical spread between items in the stack [0...1]
|
||||
private static final float PERSPECTIVE_SHIFT_FACTOR = 0.24f;
|
||||
@@ -112,18 +112,19 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
folder.bind(folderInfo);
|
||||
icon.mFolder = folder;
|
||||
icon.mFolderRingAnimator = new FolderRingAnimator(launcher, icon);
|
||||
|
||||
folderInfo.addListener(icon);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
public static class FolderRingAnimator {
|
||||
public int mFolderLocX;
|
||||
public int mFolderLocY;
|
||||
public int mCellX;
|
||||
public int mCellY;
|
||||
private CellLayout mCellLayout;
|
||||
public float mOuterRingSize;
|
||||
public float mInnerRingSize;
|
||||
public FolderIcon mFolderIcon = null;
|
||||
private Launcher mLauncher;
|
||||
public Drawable mOuterRingDrawable = null;
|
||||
public Drawable mInnerRingDrawable = null;
|
||||
public static Drawable sSharedOuterRingDrawable = null;
|
||||
@@ -135,7 +136,6 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
private ValueAnimator mNeutralAnimator;
|
||||
|
||||
public FolderRingAnimator(Launcher launcher, FolderIcon folderIcon) {
|
||||
mLauncher = launcher;
|
||||
mFolderIcon = folderIcon;
|
||||
Resources res = launcher.getResources();
|
||||
mOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo);
|
||||
@@ -153,12 +153,6 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Location is expressed in window coordinates
|
||||
public void setLocation(int x, int y) {
|
||||
mFolderLocX = x;
|
||||
mFolderLocY = y;
|
||||
}
|
||||
|
||||
public void animateToAcceptState() {
|
||||
if (mNeutralAnimator != null) {
|
||||
mNeutralAnimator.cancel();
|
||||
@@ -170,9 +164,8 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
final float percent = (Float) animation.getAnimatedValue();
|
||||
mOuterRingSize = (1 + percent * OUTER_RING_GROWTH_FACTOR) * sPreviewSize;
|
||||
mInnerRingSize = (1 + percent * INNER_RING_GROWTH_FACTOR) * sPreviewSize;
|
||||
mLauncher.getWorkspace().invalidate();
|
||||
if (mFolderIcon != null) {
|
||||
mFolderIcon.invalidate();
|
||||
if (mCellLayout != null) {
|
||||
mCellLayout.invalidate();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -198,28 +191,39 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
final float percent = (Float) animation.getAnimatedValue();
|
||||
mOuterRingSize = (1 + (1 - percent) * OUTER_RING_GROWTH_FACTOR) * sPreviewSize;
|
||||
mInnerRingSize = (1 + (1 - percent) * INNER_RING_GROWTH_FACTOR) * sPreviewSize;
|
||||
mLauncher.getWorkspace().invalidate();
|
||||
if (mFolderIcon != null) {
|
||||
mFolderIcon.invalidate();
|
||||
if (mCellLayout != null) {
|
||||
mCellLayout.invalidate();
|
||||
}
|
||||
}
|
||||
});
|
||||
mNeutralAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mCellLayout != null) {
|
||||
mCellLayout.hideFolderAccept(FolderRingAnimator.this);
|
||||
}
|
||||
if (mFolderIcon != null) {
|
||||
mFolderIcon.mPreviewBackground.setVisibility(VISIBLE);
|
||||
}
|
||||
mLauncher.getWorkspace().hideFolderAccept(FolderRingAnimator.this);
|
||||
}
|
||||
});
|
||||
mNeutralAnimator.start();
|
||||
}
|
||||
|
||||
// Location is expressed in window coordinates
|
||||
public void getLocation(int[] loc) {
|
||||
loc[0] = mFolderLocX;
|
||||
loc[1] = mFolderLocY;
|
||||
public void getCell(int[] loc) {
|
||||
loc[0] = mCellX;
|
||||
loc[1] = mCellY;
|
||||
}
|
||||
|
||||
// Location is expressed in window coordinates
|
||||
public void setCell(int x, int y) {
|
||||
mCellX = x;
|
||||
mCellY = y;
|
||||
}
|
||||
|
||||
public void setCellLayout(CellLayout layout) {
|
||||
mCellLayout = layout;
|
||||
}
|
||||
|
||||
public float getOuterRingSize() {
|
||||
@@ -253,22 +257,14 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
mOriginalHeight = lp.height;
|
||||
}
|
||||
|
||||
private void determineFolderLocationInWorkspace() {
|
||||
int tvLocation[] = new int[2];
|
||||
int wsLocation[] = new int[2];
|
||||
getLocationInWindow(tvLocation);
|
||||
mLauncher.getWorkspace().getLocationInWindow(wsLocation);
|
||||
|
||||
int x = tvLocation[0] - wsLocation[0] + getMeasuredWidth() / 2;
|
||||
int y = tvLocation[1] - wsLocation[1] + FolderRingAnimator.sPreviewSize / 2;
|
||||
mFolderRingAnimator.setLocation(x, y);
|
||||
}
|
||||
|
||||
public void onDragEnter(Object dragInfo) {
|
||||
if (!willAcceptItem((ItemInfo) dragInfo)) return;
|
||||
determineFolderLocationInWorkspace();
|
||||
mLauncher.getWorkspace().showFolderAccept(mFolderRingAnimator);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
|
||||
CellLayout layout = (CellLayout) getParent().getParent();
|
||||
mFolderRingAnimator.setCell(lp.cellX, lp.cellY);
|
||||
mFolderRingAnimator.setCellLayout(layout);
|
||||
mFolderRingAnimator.animateToAcceptState();
|
||||
layout.showFolderAccept(mFolderRingAnimator);
|
||||
}
|
||||
|
||||
public void onDragOver(Object dragInfo) {
|
||||
@@ -341,7 +337,7 @@ public class FolderIcon extends LinearLayout implements FolderListener {
|
||||
ArrayList<View> items = mFolder.getItemsInReadingOrder(false);
|
||||
|
||||
int xShift = (mOriginalWidth - 2 * halfAvailableSpace) / 2;
|
||||
int yShift = previewPadding;
|
||||
int yShift = previewPadding + getPaddingTop();
|
||||
canvas.translate(xShift, yShift);
|
||||
int nItemsInPreview = Math.min(items.size(), NUM_ITEMS_IN_PREVIEW);
|
||||
for (int i = nItemsInPreview - 1; i >= 0; i--) {
|
||||
|
||||
@@ -203,8 +203,6 @@ public class Workspace extends SmoothPagedView
|
||||
private int mLastDragXOffset;
|
||||
private int mLastDragYOffset;
|
||||
|
||||
private ArrayList<FolderRingAnimator> mFolderOuterRings = new ArrayList<FolderRingAnimator>();
|
||||
|
||||
// Variables relating to the creation of user folders by hovering shortcuts over shortcuts
|
||||
private static final int FOLDER_CREATION_TIMEOUT = 250;
|
||||
private final Alarm mFolderCreationAlarm = new Alarm();
|
||||
@@ -1127,17 +1125,6 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
}
|
||||
|
||||
public void showFolderAccept(FolderRingAnimator fra) {
|
||||
mFolderOuterRings.add(fra);
|
||||
}
|
||||
|
||||
public void hideFolderAccept(FolderRingAnimator fra) {
|
||||
if (mFolderOuterRings.contains(fra)) {
|
||||
mFolderOuterRings.remove(fra);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
updateWallpaperOffsets();
|
||||
@@ -1151,62 +1138,6 @@ public class Workspace extends SmoothPagedView
|
||||
mBackground.draw(canvas);
|
||||
}
|
||||
|
||||
// The folder outer / inner ring image(s)
|
||||
for (int i = 0; i < mFolderOuterRings.size(); i++) {
|
||||
View currentPage = getChildAt(getCurrentPage());
|
||||
Matrix m = currentPage.getMatrix();
|
||||
|
||||
FolderRingAnimator fra = mFolderOuterRings.get(i);
|
||||
|
||||
// Draw outer ring
|
||||
Drawable d = FolderRingAnimator.sSharedOuterRingDrawable;
|
||||
int width = (int) fra.getOuterRingSize();
|
||||
int height = width;
|
||||
fra.getLocation(mTempLocation);
|
||||
|
||||
// First we map the folder's location from window coordinates to its containing
|
||||
// CellLayout's coordinates. Then we transform the coordinates according to the
|
||||
// CellLayout's transform. Finally, we map this back into the coordinates of the
|
||||
// the window (ie. Workspace).
|
||||
int x = mTempLocation[0] + mScrollX - width / 2 - currentPage.getLeft();
|
||||
int y = mTempLocation[1] + mScrollY - height / 2 - currentPage.getTop();
|
||||
mTempFloatTuple[0] = x;
|
||||
mTempFloatTuple[1] = y;
|
||||
m.mapPoints(mTempFloatTuple);
|
||||
x = (int) (mTempFloatTuple[0]) + currentPage.getLeft();
|
||||
y = (int) (mTempFloatTuple[1]) + currentPage.getTop();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(x, y);
|
||||
d.setBounds(0, 0, (int) (width * currentPage.getScaleX()),
|
||||
(int) (height * currentPage.getScaleY()));
|
||||
d.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
// Draw inner ring
|
||||
d = FolderRingAnimator.sSharedInnerRingDrawable;
|
||||
width = (int) fra.getInnerRingSize();
|
||||
height = width;
|
||||
|
||||
// First we map the folder's location from window coordinates to its containing
|
||||
// CellLayout's coordinates. Then we transform the coordinates according to the
|
||||
// CellLayout's transform. Finally, we map this back into the coordinates of the
|
||||
// the window (ie. Workspace).
|
||||
x = mTempLocation[0] + mScrollX - width / 2 - currentPage.getLeft();
|
||||
y = mTempLocation[1] + mScrollY - height / 2 - currentPage.getTop();
|
||||
mTempFloatTuple[0] = x;
|
||||
mTempFloatTuple[1] = y;
|
||||
m.mapPoints(mTempFloatTuple);
|
||||
x = (int) (mTempFloatTuple[0]) + currentPage.getLeft();
|
||||
y = (int) (mTempFloatTuple[1]) + currentPage.getTop();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(x, y);
|
||||
d.setBounds(0, 0, (int) (width * currentPage.getScaleX()),
|
||||
(int) (height * currentPage.getScaleY()));
|
||||
d.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
@@ -2808,12 +2739,11 @@ public class Workspace extends SmoothPagedView
|
||||
|
||||
if (userFolderPending && dragOverView != mLastDragOverView) {
|
||||
mFolderCreationAlarm.setOnAlarmListener(new
|
||||
FolderCreationAlarmListener(dragOverView));
|
||||
FolderCreationAlarmListener(mDragTargetLayout, mTargetCell[0], mTargetCell[1]));
|
||||
mFolderCreationAlarm.setAlarm(FOLDER_CREATION_TIMEOUT);
|
||||
}
|
||||
|
||||
if (dragOverView != mLastDragOverView && isOverFolder) {
|
||||
|
||||
((FolderIcon) dragOverView).onDragEnter(d.dragInfo);
|
||||
if (mDragTargetLayout != null) {
|
||||
mDragTargetLayout.clearDragOutlines();
|
||||
@@ -2840,36 +2770,26 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
|
||||
class FolderCreationAlarmListener implements OnAlarmListener {
|
||||
View v;
|
||||
CellLayout layout;
|
||||
int cellX;
|
||||
int cellY;
|
||||
|
||||
public FolderCreationAlarmListener(View v) {
|
||||
this.v = v;
|
||||
public FolderCreationAlarmListener(CellLayout layout, int cellX, int cellY) {
|
||||
this.layout = layout;
|
||||
this.cellX = cellX;
|
||||
this.cellY = cellY;
|
||||
}
|
||||
|
||||
public void onAlarm(Alarm alarm) {
|
||||
int tvLocation[] = new int[2];
|
||||
int wsLocation[] = new int[2];
|
||||
v.getLocationInWindow(tvLocation);
|
||||
getLocationInWindow(wsLocation);
|
||||
|
||||
if (mCellWidth < 0 || mCellHeight < 0 && mDragTargetLayout != null) {
|
||||
mCellWidth = mDragTargetLayout.getCellWidth();
|
||||
mCellHeight = mDragTargetLayout.getCellHeight();
|
||||
}
|
||||
|
||||
int x = tvLocation[0] - wsLocation[0] + v.getMeasuredWidth() / 2;
|
||||
int y = tvLocation[1] - wsLocation[1] + FolderRingAnimator.sPreviewSize / 2;
|
||||
|
||||
if (mDragFolderRingAnimator == null) {
|
||||
mDragFolderRingAnimator = new FolderRingAnimator(mLauncher, null);
|
||||
}
|
||||
mDragFolderRingAnimator.setLocation(x, y);
|
||||
mDragFolderRingAnimator.setCell(cellX, cellY);
|
||||
mDragFolderRingAnimator.setCellLayout(layout);
|
||||
mDragFolderRingAnimator.animateToAcceptState();
|
||||
showFolderAccept(mDragFolderRingAnimator);
|
||||
layout.showFolderAccept(mDragFolderRingAnimator);
|
||||
layout.clearDragOutlines();
|
||||
mCreateUserFolderOnDrop = true;
|
||||
if (mDragTargetLayout != null) {
|
||||
mDragTargetLayout.clearDragOutlines();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user