Merge "Slide in first page preview items in FolderIcon after Folder closes." into ub-launcher3-dorval-polish
This commit is contained in:
committed by
Android (Google) Code Review
commit
cebce95bac
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user