summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/folder
diff options
context:
space:
mode:
authorJon Miranda <jonmiranda@google.com>2017-07-06 16:31:56 -0700
committerJon Miranda <jonmiranda@google.com>2017-07-10 11:28:57 -0700
commit27bdbcae7fc43612c6016f625038e93bb3bd1e7b (patch)
treecf0d399b517873a2d68882c433b3f026fe40dd36 /src/com/android/launcher3/folder
parent6c5d10261eceaf1b57bce82e4e31d272bad2c349 (diff)
downloadandroid_packages_apps_Trebuchet-27bdbcae7fc43612c6016f625038e93bb3bd1e7b.tar.gz
android_packages_apps_Trebuchet-27bdbcae7fc43612c6016f625038e93bb3bd1e7b.tar.bz2
android_packages_apps_Trebuchet-27bdbcae7fc43612c6016f625038e93bb3bd1e7b.zip
Slide in first page preview items in FolderIcon after Folder closes.
If the Folder is not closed on on the first page, we animate the current page items as if they are in the preview. When the Folder finishes closing, the first page preview items slide in as the current page preview items slide out. Bug: 36022592 Bug: 35064148 Change-Id: I7ede7ed9e091e2a0c3cbe11731744bfe9ce36595
Diffstat (limited to 'src/com/android/launcher3/folder')
-rw-r--r--src/com/android/launcher3/folder/Folder.java20
-rw-r--r--src/com/android/launcher3/folder/FolderAnimationManager.java20
-rw-r--r--src/com/android/launcher3/folder/FolderIcon.java24
-rw-r--r--src/com/android/launcher3/folder/FolderIconPreviewVerifier.java34
-rw-r--r--src/com/android/launcher3/folder/PreviewItemManager.java94
5 files changed, 152 insertions, 40 deletions
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index afbf9f2a2..3184d6d43 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -791,12 +791,14 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
if (mFolderIcon != null) {
mFolderIcon.setVisibility(View.VISIBLE);
if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
- mFolderIcon.mFolderName.setTextVisibility(true);
mFolderIcon.setBackgroundVisible(true);
- mFolderIcon.mBackground.fadeInBackgroundShadow();
}
if (wasAnimated) {
- mFolderIcon.mBackground.animateBackgroundStroke();
+ if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+ mFolderIcon.mBackground.fadeInBackgroundShadow();
+ mFolderIcon.mBackground.animateBackgroundStroke();
+ mFolderIcon.onFolderClose(mContent.getCurrentPage());
+ }
if (mFolderIcon.hasBadge()) {
mFolderIcon.createBadgeScaleAnimator(0f, 1f).start();
}
@@ -818,6 +820,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
mSuppressFolderDeletion = false;
clearDragInfo();
mState = STATE_SMALL;
+ mContent.setCurrentPage(0);
}
public boolean acceptDrop(DragObject d) {
@@ -1516,18 +1519,17 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
return itemsInReadingOrder;
}
- public List<BubbleTextView> getItemsOnCurrentPage() {
+ public List<BubbleTextView> getItemsOnPage(int page) {
ArrayList<View> allItems = getItemsInRankOrder();
- int currentPage = mContent.getCurrentPage();
int lastPage = mContent.getPageCount() - 1;
int totalItemsInFolder = allItems.size();
int itemsPerPage = mContent.itemsPerPage();
- int numItemsOnCurrentPage = currentPage == lastPage
- ? totalItemsInFolder - (itemsPerPage * currentPage)
+ int numItemsOnCurrentPage = page == lastPage
+ ? totalItemsInFolder - (itemsPerPage * page)
: itemsPerPage;
- int startIndex = currentPage * itemsPerPage;
- int endIndex = startIndex + numItemsOnCurrentPage;
+ int startIndex = page * itemsPerPage;
+ int endIndex = Math.min(startIndex + numItemsOnCurrentPage, allItems.size());
List<BubbleTextView> itemsOnCurrentPage = new ArrayList<>(numItemsOnCurrentPage);
for (int i = startIndex; i < endIndex; ++i) {
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index 7e8d0c7cd..26a2c8913 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -119,7 +119,7 @@ public class FolderAnimationManager {
public AnimatorSet getAnimator() {
final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) mFolder.getLayoutParams();
FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule();
- final List<BubbleTextView> itemsInPreview = mFolderIcon.getItemsToDisplay();
+ final List<BubbleTextView> itemsInPreview = mFolderIcon.getPreviewItems();
// Match position of the FolderIcon
final Rect folderIconPos = new Rect();
@@ -186,7 +186,7 @@ public class FolderAnimationManager {
PropertyResetListener colorResetListener = new PropertyResetListener<>(
BubbleTextView.TEXT_ALPHA_PROPERTY,
Color.alpha(Themes.getAttrColor(mContext, android.R.attr.textColorSecondary)));
- for (BubbleTextView icon : mFolder.getItemsOnCurrentPage()) {
+ for (BubbleTextView icon : mFolder.getItemsOnPage(mFolder.mContent.getCurrentPage())) {
if (mIsOpening) {
icon.setTextVisibility(false);
}
@@ -237,13 +237,19 @@ public class FolderAnimationManager {
}
/**
- * Animate the items that are displayed in the preview.
+ * Animate the items on the current page.
*/
private void addPreviewItemAnimators(AnimatorSet animatorSet, final float folderScale,
int previewItemOffsetX) {
FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule();
- final List<BubbleTextView> itemsInPreview = mFolderIcon.getItemsToDisplay();
+ boolean isOnFirstPage = mFolder.mContent.getCurrentPage() == 0;
+ final List<BubbleTextView> itemsInPreview = isOnFirstPage
+ ? mFolderIcon.getPreviewItems()
+ : mFolderIcon.getPreviewItemsOnPage(mFolder.mContent.getCurrentPage());
final int numItemsInPreview = itemsInPreview.size();
+ final int numItemsInFirstPagePreview = isOnFirstPage
+ ? numItemsInPreview
+ : FolderIcon.NUM_ITEMS_IN_PREVIEW;
TimeInterpolator previewItemInterpolator = getPreviewItemInterpolator();
@@ -256,8 +262,8 @@ public class FolderAnimationManager {
btvLp.isLockedToGrid = true;
cwc.setupLp(btv);
- // Match scale of icons in the preview.
- float previewScale = rule.scaleForItem(i, numItemsInPreview);
+ // Match scale of icons in the preview of the items on the first page.
+ float previewScale = rule.scaleForItem(i, numItemsInFirstPagePreview);
float previewSize = rule.getIconSize() * previewScale;
float iconScale = previewSize / itemsInPreview.get(i).getIconSize();
@@ -268,7 +274,7 @@ public class FolderAnimationManager {
btv.setScaleY(scale);
// Match positions of the icons in the folder with their positions in the preview
- rule.computePreviewItemDrawingParams(i, numItemsInPreview, mTmpParams);
+ rule.computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, mTmpParams);
// The PreviewLayoutRule assumes that the icon size takes up the entire width so we
// offset by the actual size.
int iconOffsetX = (int) ((btvLp.width - btv.getIconSize()) * iconScale) / 2;
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 7fdacc094..ae6a0e86d 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -471,15 +471,25 @@ public class FolderIcon extends FrameLayout implements FolderListener {
return mFolderName.getVisibility() == VISIBLE;
}
- public List<BubbleTextView> getItemsToDisplay() {
+ /**
+ * Returns the list of preview items displayed in the icon.
+ */
+ public List<BubbleTextView> getPreviewItems() {
+ return getPreviewItemsOnPage(0);
+ }
+
+ /**
+ * Returns the list of "preview items" on {@param page}.
+ */
+ public List<BubbleTextView> getPreviewItemsOnPage(int page) {
mPreviewVerifier.setFolderInfo(mFolder.getInfo());
List<BubbleTextView> itemsToDisplay = new ArrayList<>();
- List<View> allItems = mFolder.getItemsInRankOrder();
- int numItems = allItems.size();
+ List<BubbleTextView> itemsOnPage = mFolder.getItemsOnPage(page);
+ int numItems = itemsOnPage.size();
for (int rank = 0; rank < numItems; ++rank) {
- if (mPreviewVerifier.isItemInPreview(rank)) {
- itemsToDisplay.add((BubbleTextView) allItems.get(rank));
+ if (mPreviewVerifier.isItemInPreview(page, rank)) {
+ itemsToDisplay.add(itemsOnPage.get(rank));
}
if (itemsToDisplay.size() == FolderIcon.NUM_ITEMS_IN_PREVIEW) {
@@ -639,6 +649,10 @@ public class FolderIcon extends FrameLayout implements FolderListener {
}
}
+ public void onFolderClose(int currentPage) {
+ mPreviewItemManager.onFolderClose(currentPage);
+ }
+
interface PreviewLayoutRule {
PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
PreviewItemDrawingParams params);
diff --git a/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java
index d0d8e79d5..eb415b945 100644
--- a/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java
+++ b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java
@@ -25,15 +25,45 @@ import com.android.launcher3.config.FeatureFlags;
*/
public class FolderIconPreviewVerifier {
+ private final int mMaxGridCountX;
+ private final int mMaxGridCountY;
+ private final int mMaxItemsPerPage;
+ private final int[] mGridSize = new int[2];
+
+ private int mGridCountX;
+
public FolderIconPreviewVerifier(InvariantDeviceProfile profile) {
- // b/37570804
+ mMaxGridCountX = profile.numFolderColumns;
+ mMaxGridCountY = profile.numFolderRows;
+ mMaxItemsPerPage = mMaxGridCountX * mMaxGridCountY;
}
public void setFolderInfo(FolderInfo info) {
- // b/37570804
+ FolderPagedView.calculateGridSize(info.contents.size(), 0, 0, mMaxGridCountX,
+ mMaxGridCountY, mMaxItemsPerPage, mGridSize);
+ mGridCountX = mGridSize[0];
}
+ /**
+ * Returns whether the item with {@param rank} is in the default Folder icon preview.
+ */
public boolean isItemInPreview(int rank) {
+ return isItemInPreview(0, rank);
+ }
+
+ /**
+ * @param page The page the item is on.
+ * @param rank The rank of the item.
+ * @return True iff the icon is in the 2x2 upper left quadrant of the Folder.
+ */
+ public boolean isItemInPreview(int page, int rank) {
+ if (page > 0) {
+ // First page items are laid out such that the first 4 items are always in the upper
+ // left quadrant. For all other pages, we need to check the row and col.
+ int col = rank % mGridCountX;
+ int row = rank / mGridCountX;
+ return col < 2 && row < 2;
+ }
return rank < FolderIcon.NUM_ITEMS_IN_PREVIEW;
}
}
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index 2524a6d82..74c210254 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -16,6 +16,9 @@
package com.android.launcher3.folder;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -48,10 +51,19 @@ public class PreviewItemManager {
// These hold the first page preview items
private ArrayList<PreviewItemDrawingParams> mFirstPageParams = new ArrayList<>();
+ // These hold the current page preview items. It is empty if the current page is the first page.
+ private ArrayList<PreviewItemDrawingParams> mCurrentPageParams = new ArrayList<>();
+
+ private float mCurrentPageItemsTransX = 0;
+ private boolean mShouldSlideInFirstPage;
static final int INITIAL_ITEM_ANIMATION_DURATION = 350;
private static final int FINAL_ITEM_ANIMATION_DURATION = 200;
+ private static final int SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION_DELAY = 200;
+ private static final int SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION = 300;
+ private static final int ITEM_SLIDE_IN_OUT_DISTANCE_PX = 200;
+
public PreviewItemManager(FolderIcon icon) {
mIcon = icon;
}
@@ -116,15 +128,30 @@ public class PreviewItemManager {
return params;
}
- public void draw(Canvas canvas) {
- computePreviewDrawingParams(mReferenceDrawable);
+ public void drawParams(Canvas canvas, ArrayList<PreviewItemDrawingParams> params,
+ float transX) {
+ canvas.translate(transX, 0);
// The first item should be drawn last (ie. on top of later items)
- for (int i = mFirstPageParams.size() - 1; i >= 0; i--) {
- PreviewItemDrawingParams p = mFirstPageParams.get(i);
+ for (int i = params.size() - 1; i >= 0; i--) {
+ PreviewItemDrawingParams p = params.get(i);
if (!p.hidden) {
drawPreviewItem(canvas, p);
}
}
+ canvas.translate(-transX, 0);
+ }
+
+ public void draw(Canvas canvas) {
+ computePreviewDrawingParams(mReferenceDrawable);
+
+ float firstPageItemsTransX = 0;
+ if (mShouldSlideInFirstPage) {
+ drawParams(canvas, mCurrentPageParams, mCurrentPageItemsTransX);
+
+ firstPageItemsTransX = -ITEM_SLIDE_IN_OUT_DISTANCE_PX + mCurrentPageItemsTransX;
+ }
+
+ drawParams(canvas, mFirstPageParams, firstPageItemsTransX);
}
public void onParamsChanged() {
@@ -156,21 +183,21 @@ public class PreviewItemManager {
}
}
- void updateItemDrawingParams(boolean animate) {
- List<BubbleTextView> items = mIcon.getItemsToDisplay();
- int numItemsInPreview = items.size();
- int prevNumItems = mFirstPageParams.size();
+ void buildParamsForPage(int page, ArrayList<PreviewItemDrawingParams> params, boolean animate) {
+ List<BubbleTextView> items = mIcon.getPreviewItemsOnPage(page);
+ int prevNumItems = params.size();
- // We adjust the size of the list to match the number of items in the preview
- while (numItemsInPreview < mFirstPageParams.size()) {
- mFirstPageParams.remove(mFirstPageParams.size() - 1);
+ // We adjust the size of the list to match the number of items in the preview.
+ while (items.size() < params.size()) {
+ params.remove(params.size() - 1);
}
- while (numItemsInPreview > mFirstPageParams.size()) {
- mFirstPageParams.add(new PreviewItemDrawingParams(0, 0, 0, 0));
+ while (items.size() > params.size()) {
+ params.add(new PreviewItemDrawingParams(0, 0, 0, 0));
}
- for (int i = 0; i < mFirstPageParams.size(); i++) {
- PreviewItemDrawingParams p = mFirstPageParams.get(i);
+ int numItemsInFirstPagePreview = page == 0 ? items.size() : FolderIcon.NUM_ITEMS_IN_PREVIEW;
+ for (int i = 0; i < params.size(); i++) {
+ PreviewItemDrawingParams p = params.get(i);
p.drawable = items.get(i).getCompoundDrawables()[1];
if (p.drawable != null && !mIcon.mFolder.isOpen()) {
@@ -180,13 +207,13 @@ public class PreviewItemManager {
}
if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) {
- computePreviewItemDrawingParams(i, numItemsInPreview, p);
+ computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, p);
if (mReferenceDrawable == null) {
mReferenceDrawable = p.drawable;
}
} else {
FolderPreviewItemAnim anim = new FolderPreviewItemAnim(this, p, i, prevNumItems, i,
- numItemsInPreview, DROP_IN_ANIMATION_DURATION, null);
+ numItemsInFirstPagePreview, DROP_IN_ANIMATION_DURATION, null);
if (p.anim != null) {
if (p.anim.hasEqualFinalState(anim)) {
@@ -201,6 +228,39 @@ public class PreviewItemManager {
}
}
+ void onFolderClose(int currentPage) {
+ // If we are not closing on the first page, we animate the current page preview items
+ // out, and animate the first page preview items in.
+ mShouldSlideInFirstPage = currentPage != 0;
+ if (mShouldSlideInFirstPage) {
+ mCurrentPageItemsTransX = 0;
+ buildParamsForPage(currentPage, mCurrentPageParams, false);
+ onParamsChanged();
+
+ ValueAnimator slideAnimator = ValueAnimator.ofFloat(0, ITEM_SLIDE_IN_OUT_DISTANCE_PX);
+ slideAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ mCurrentPageItemsTransX = (float) valueAnimator.getAnimatedValue();
+ onParamsChanged();
+ }
+ });
+ slideAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mCurrentPageParams.clear();
+ }
+ });
+ slideAnimator.setStartDelay(SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION_DELAY);
+ slideAnimator.setDuration(SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION);
+ slideAnimator.start();
+ }
+ }
+
+ void updateItemDrawingParams(boolean animate) {
+ buildParamsForPage(0, mFirstPageParams, animate);
+ }
+
boolean verifyDrawable(@NonNull Drawable who) {
for (int i = 0; i < mFirstPageParams.size(); i++) {
if (mFirstPageParams.get(i).drawable == who) {