Loading res/values/config.xml +0 −5 Original line number Diff line number Diff line Loading @@ -86,9 +86,7 @@ <integer name="config_dropAnimMaxDuration">500</integer> <!-- The duration of the UserFolder opening and closing animation --> <integer name="config_folderExpandDuration">120</integer> <integer name="config_materialFolderExpandDuration">200</integer> <integer name="config_materialFolderExpandStagger">60</integer> <integer name="config_folderDelay">30</integer> <!-- The distance at which the animation should take the max duration --> Loading Loading @@ -128,9 +126,6 @@ <!-- View ID used by cell layout to jail its content --> <item type="id" name="cell_layout_jail_id" /> <!-- View ID used by PreviewImageView to cache its instance --> <item type="id" name="preview_image_id" /> <!-- Popup items --> <integer name="config_popupOpenCloseDuration">150</integer> <integer name="config_popupArrowOpenDuration">80</integer> Loading src/com/android/launcher3/config/BaseFlags.java +0 −2 Original line number Diff line number Diff line Loading @@ -32,9 +32,7 @@ abstract class BaseFlags { // Custom flags go below this public static boolean LAUNCHER3_DISABLE_ICON_NORMALIZATION = false; public static boolean LAUNCHER3_LEGACY_FOLDER_ICON = false; public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false; public static boolean LAUNCHER3_NEW_FOLDER_ANIMATION = true; // When enabled allows to use any point on the fast scrollbar to start dragging. public static final boolean LAUNCHER3_DIRECT_SCROLL = true; // When enabled while all-apps open, the soft input will be set to adjust resize . Loading src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java +10 −41 Original line number Diff line number Diff line package com.android.launcher3.folder; public class ClippedFolderIconLayoutRule { public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule { static final int MAX_NUM_ITEMS_IN_PREVIEW = 4; public static final int MAX_NUM_ITEMS_IN_PREVIEW = 4; private static final int MIN_NUM_ITEMS_IN_PREVIEW = 2; private static final float MIN_SCALE = 0.48f; Loading @@ -11,8 +10,8 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule 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; public static final int EXIT_INDEX = -2; public static final int ENTER_INDEX = -3; private float[] mTmpPoint = new float[2]; Loading @@ -22,7 +21,6 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule private boolean mIsRtl; private float mBaselineIconScale; @Override public void init(int availableSpace, float intrinsicIconSize, boolean rtl) { mAvailableSpace = availableSpace; mRadius = ITEM_RADIUS_SCALE_FACTOR * availableSpace / 2f; Loading @@ -31,19 +29,18 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule mBaselineIconScale = availableSpace / (intrinsicIconSize * 1f); } @Override public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, PreviewItemDrawingParams params) { float totalScale = scaleForItem(index, curNumItems); float totalScale = scaleForItem(curNumItems); float transX; float transY; float overlayAlpha = 0; if (index == getExitIndex()) { if (index == EXIT_INDEX) { // 0 1 * <-- Exit position (row 0, col 2) // 2 3 getGridPosition(0, 2, mTmpPoint); } else if (index == getEnterIndex()) { } else if (index == ENTER_INDEX) { // 0 1 // 2 3 * <-- Enter position (row 1, col 2) getGridPosition(1, 2, mTmpPoint); Loading Loading @@ -120,7 +117,7 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule MIN_NUM_ITEMS_IN_PREVIEW) / (MAX_NUM_ITEMS_IN_PREVIEW - MIN_NUM_ITEMS_IN_PREVIEW)); double theta = theta0 + index * (2 * Math.PI / curNumItems) * direction; float halfIconSize = (mIconSize * scaleForItem(index, curNumItems)) / 2; float halfIconSize = (mIconSize * scaleForItem(curNumItems)) / 2; // Map the location along the circle, and offset the coordinates to represent the center // of the icon, and to be based from the top / left of the preview area. The y component Loading @@ -130,10 +127,9 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule } @Override public float scaleForItem(int index, int numItems) { public float scaleForItem(int numItems) { // Scale is determined by the number of items in the preview. float scale = 1f; final float scale; if (numItems <= 2) { scale = MAX_SCALE; } else if (numItems == 3) { Loading @@ -141,37 +137,10 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule } else { scale = MIN_SCALE; } return scale * mBaselineIconScale; } @Override public float getIconSize() { return mIconSize; } @Override public int maxNumItems() { return MAX_NUM_ITEMS_IN_PREVIEW; } @Override 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; } } src/com/android/launcher3/folder/Folder.java +15 −137 Original line number Diff line number Diff line Loading @@ -19,8 +19,6 @@ package com.android.launcher3.folder; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; Loading @@ -37,7 +35,6 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewDebug; import android.view.accessibility.AccessibilityEvent; import android.view.animation.AccelerateInterpolator; import android.view.animation.AnimationUtils; import android.view.inputmethod.EditorInfo; import android.widget.TextView; Loading @@ -55,9 +52,7 @@ import com.android.launcher3.FolderInfo; import com.android.launcher3.FolderInfo.FolderListener; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LogDecelerateInterpolator; import com.android.launcher3.OnAlarmListener; import com.android.launcher3.PagedView; import com.android.launcher3.R; Loading @@ -66,8 +61,6 @@ import com.android.launcher3.UninstallDropTarget.DropTargetSource; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace.ItemOperator; import com.android.launcher3.accessibility.AccessibleDragListenerAdapter; import com.android.launcher3.anim.AnimationLayerSet; import com.android.launcher3.anim.CircleRevealOutlineProvider; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragController.DragListener; Loading Loading @@ -137,10 +130,6 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC private AnimatorSet mCurrentAnimator; private final int mExpandDuration; public final int mMaterialExpandDuration; private final int mMaterialExpandStagger; protected final Launcher mLauncher; protected DragController mDragController; public FolderInfo mInfo; Loading Loading @@ -201,9 +190,6 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC super(context, attrs); setAlwaysDrawnWithCacheEnabled(false); Resources res = getResources(); mExpandDuration = res.getInteger(R.integer.config_folderExpandDuration); mMaterialExpandDuration = res.getInteger(R.integer.config_materialFolderExpandDuration); mMaterialExpandStagger = res.getInteger(R.integer.config_materialFolderExpandStagger); if (sDefaultFolderName == null) { sDefaultFolderName = res.getString(R.string.folder_name); Loading Loading @@ -487,25 +473,6 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC ? R.layout.user_folder : R.layout.user_folder_icon_normalized, null); } /** * This method is intended to make the UserFolder to be visually identical in size and position * to its associated FolderIcon. This allows for a seamless transition into the expanded state. */ private void positionAndSizeAsIcon() { if (!(getParent() instanceof DragLayer)) return; setScaleX(0.8f); setScaleY(0.8f); setAlpha(0f); mState = STATE_SMALL; } private void prepareReveal() { setScaleX(1f); setScaleY(1f); setAlpha(1f); mState = STATE_SMALL; } private void startAnimation(final AnimatorSet a) { if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) { mCurrentAnimator.cancel(); Loading @@ -525,61 +492,6 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC a.start(); } private AnimatorSet getOpeningAnimator() { prepareReveal(); mFolderIcon.growAndFadeOut(); AnimatorSet anim = LauncherAnimUtils.createAnimatorSet(); int width = getFolderWidth(); int height = getFolderHeight(); float transX = - 0.075f * (width / 2 - getPivotX()); float transY = - 0.075f * (height / 2 - getPivotY()); setTranslationX(transX); setTranslationY(transY); PropertyValuesHolder tx = PropertyValuesHolder.ofFloat(TRANSLATION_X, transX, 0); PropertyValuesHolder ty = PropertyValuesHolder.ofFloat(TRANSLATION_Y, transY, 0); Animator drift = ObjectAnimator.ofPropertyValuesHolder(this, tx, ty); drift.setDuration(mMaterialExpandDuration); drift.setStartDelay(mMaterialExpandStagger); drift.setInterpolator(new LogDecelerateInterpolator(100, 0)); int rx = (int) Math.max(Math.max(width - getPivotX(), 0), getPivotX()); int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY()); float radius = (float) Math.hypot(rx, ry); Animator reveal = new CircleRevealOutlineProvider((int) getPivotX(), (int) getPivotY(), 0, radius).createRevealAnimator(this); reveal.setDuration(mMaterialExpandDuration); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); mContent.setAlpha(0f); Animator iconsAlpha = ObjectAnimator.ofFloat(mContent, "alpha", 0f, 1f); iconsAlpha.setDuration(mMaterialExpandDuration); iconsAlpha.setStartDelay(mMaterialExpandStagger); iconsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); mFooter.setAlpha(0f); Animator textAlpha = ObjectAnimator.ofFloat(mFooter, "alpha", 0f, 1f); textAlpha.setDuration(mMaterialExpandDuration); textAlpha.setStartDelay(mMaterialExpandStagger); textAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); anim.play(drift); anim.play(iconsAlpha); anim.play(textAlpha); anim.play(reveal); AnimationLayerSet layerSet = new AnimationLayerSet(); layerSet.addView(mContent); layerSet.addView(mFooter); anim.addListener(layerSet); return anim; } /** * Opens the user folder described by the specified tag. The opening of the folder * is animated relative to the specified View. If the View is null, no animation Loading Loading @@ -621,9 +533,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC final Runnable onCompleteRunnable; centerAboutIcon(); AnimatorSet anim = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION ? new FolderAnimationManager(this, true /* isOpening */).getAnimator() : getOpeningAnimator(); AnimatorSet anim = new FolderAnimationManager(this, true /* isOpening */).getAnimator(); onCompleteRunnable = new Runnable() { @Override public void run() { Loading @@ -633,12 +543,8 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { mFolderIcon.setBackgroundVisible(false); mFolderIcon.drawLeaveBehindIfExists(); } else { mFolderIcon.setVisibility(INVISIBLE); } Utilities.sendCustomAccessibilityEvent( Folder.this, Loading Loading @@ -728,11 +634,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC } if (mFolderIcon != null) { if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { mFolderIcon.clearLeaveBehindIfExists(); } else { mFolderIcon.shrinkAndFadeIn(animate); } } if (!(getParent() instanceof DragLayer)) return; Loading @@ -749,21 +651,8 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC parent.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } private AnimatorSet getClosingAnimator() { AnimatorSet animatorSet = LauncherAnimUtils.createAnimatorSet(); animatorSet.play(LauncherAnimUtils.ofViewAlphaAndScale(this, 0, 0.9f, 0.9f)); AnimationLayerSet layerSet = new AnimationLayerSet(); layerSet.addView(this); animatorSet.addListener(layerSet); animatorSet.setDuration(mExpandDuration); return animatorSet; } private void animateClosed() { AnimatorSet a = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION ? new FolderAnimationManager(this, false /* isOpening */).getAnimator() : getClosingAnimator(); AnimatorSet a = new FolderAnimationManager(this, false /* isOpening */).getAnimator(); a.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Loading @@ -790,16 +679,12 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC clearFocus(); if (mFolderIcon != null) { mFolderIcon.setVisibility(View.VISIBLE); if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { mFolderIcon.setBackgroundVisible(true); mFolderIcon.mFolderName.setTextVisibility(true); } if (wasAnimated) { if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { mFolderIcon.mBackground.fadeInBackgroundShadow(); mFolderIcon.mBackground.animateBackgroundStroke(); mFolderIcon.onFolderClose(mContent.getCurrentPage()); } if (mFolderIcon.hasBadge()) { mFolderIcon.createBadgeScaleAnimator(0f, 1f).start(); } Loading Loading @@ -852,18 +737,14 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC return (getLayoutDirection() == LAYOUT_DIRECTION_RTL); } @Override public void onDragOver(DragObject d) { onDragOver(d, REORDER_DELAY); } private int getTargetRank(DragObject d, float[] recycle) { recycle = d.getVisualCenter(recycle); return mContent.findNearestArea( (int) recycle[0] - getPaddingLeft(), (int) recycle[1] - getPaddingTop()); } @Thunk void onDragOver(DragObject d, int reorderDelay) { @Override public void onDragOver(DragObject d) { if (mScrollPauseAlarm.alarmPending()) { return; } Loading Loading @@ -1095,11 +976,8 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC } public boolean isDropEnabled() { if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { return mState != STATE_ANIMATING; } return true; } public boolean isFull() { return mContent.isFull(); Loading @@ -1113,7 +991,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC int width = getFolderWidth(); int height = getFolderHeight(); float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, sTempRect); parent.getDescendantRectRelativeToSelf(mFolderIcon, sTempRect); int centerX = sTempRect.centerX(); int centerY = sTempRect.centerY(); int centeredLeft = centerX - width / 2; Loading Loading @@ -1611,7 +1489,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC @Override public void onAlarm(Alarm alarm) { // Reorder immediately on page change. onDragOver(mDragObject, 1); onDragOver(mDragObject); } } Loading src/com/android/launcher3/folder/FolderAnimationManager.java +13 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.content.Context; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.GradientDrawable; Loading @@ -44,6 +45,8 @@ import com.android.launcher3.util.Themes; import java.util.List; import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW; /** * Manages the opening and closing animations for a {@link Folder}. * Loading Loading @@ -101,8 +104,9 @@ public class FolderAnimationManager { mIsOpening = isOpening; mDuration = mFolder.mMaterialExpandDuration; mDelay = mContext.getResources().getInteger(R.integer.config_folderDelay); Resources res = mContent.getResources(); mDuration = res.getInteger(R.integer.config_materialFolderExpandDuration); mDelay = res.getInteger(R.integer.config_folderDelay); mFolderInterpolator = AnimationUtils.loadInterpolator(mContext, R.interpolator.folder_interpolator); Loading @@ -118,7 +122,7 @@ public class FolderAnimationManager { */ public AnimatorSet getAnimator() { final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) mFolder.getLayoutParams(); FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule(); ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule(); final List<BubbleTextView> itemsInPreview = mFolderIcon.getPreviewItems(); // Match position of the FolderIcon Loading @@ -129,7 +133,7 @@ public class FolderAnimationManager { float initialSize = (scaledRadius * 2) * scaleRelativeToDragLayer; // Match size/scale of icons in the preview float previewScale = rule.scaleForItem(0, itemsInPreview.size()); float previewScale = rule.scaleForItem(itemsInPreview.size()); float previewSize = rule.getIconSize() * previewScale; float initialScale = previewSize / itemsInPreview.get(0).getIconSize() * scaleRelativeToDragLayer; Loading Loading @@ -242,15 +246,14 @@ public class FolderAnimationManager { */ private void addPreviewItemAnimators(AnimatorSet animatorSet, final float folderScale, int previewItemOffsetX, int previewItemOffsetY) { FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule(); ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule(); 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; ? numItemsInPreview : MAX_NUM_ITEMS_IN_PREVIEW; TimeInterpolator previewItemInterpolator = getPreviewItemInterpolator(); Loading @@ -264,7 +267,7 @@ public class FolderAnimationManager { cwc.setupLp(btv); // Match scale of icons in the preview of the items on the first page. float previewScale = rule.scaleForItem(i, numItemsInFirstPagePreview); float previewScale = rule.scaleForItem(numItemsInFirstPagePreview); float previewSize = rule.getIconSize() * previewScale; float iconScale = previewSize / itemsInPreview.get(i).getIconSize(); Loading Loading @@ -299,7 +302,7 @@ public class FolderAnimationManager { scaleAnimator.setInterpolator(previewItemInterpolator); play(animatorSet, scaleAnimator); if (mFolder.getItemCount() > FolderIcon.NUM_ITEMS_IN_PREVIEW) { if (mFolder.getItemCount() > MAX_NUM_ITEMS_IN_PREVIEW) { // These delays allows the preview items to move as part of the Folder's motion, // and its only necessary for large folders because of differing interpolators. int delay = mIsOpening ? mDelay : mDelay * 2; Loading Loading @@ -349,7 +352,7 @@ public class FolderAnimationManager { } private TimeInterpolator getPreviewItemInterpolator() { if (mFolder.getItemCount() > FolderIcon.NUM_ITEMS_IN_PREVIEW) { if (mFolder.getItemCount() > MAX_NUM_ITEMS_IN_PREVIEW) { // With larger folders, we want the preview items to reach their final positions faster // (when opening) and later (when closing) so that they appear aligned with the rest of // the folder items when they are both visible. Loading Loading
res/values/config.xml +0 −5 Original line number Diff line number Diff line Loading @@ -86,9 +86,7 @@ <integer name="config_dropAnimMaxDuration">500</integer> <!-- The duration of the UserFolder opening and closing animation --> <integer name="config_folderExpandDuration">120</integer> <integer name="config_materialFolderExpandDuration">200</integer> <integer name="config_materialFolderExpandStagger">60</integer> <integer name="config_folderDelay">30</integer> <!-- The distance at which the animation should take the max duration --> Loading Loading @@ -128,9 +126,6 @@ <!-- View ID used by cell layout to jail its content --> <item type="id" name="cell_layout_jail_id" /> <!-- View ID used by PreviewImageView to cache its instance --> <item type="id" name="preview_image_id" /> <!-- Popup items --> <integer name="config_popupOpenCloseDuration">150</integer> <integer name="config_popupArrowOpenDuration">80</integer> Loading
src/com/android/launcher3/config/BaseFlags.java +0 −2 Original line number Diff line number Diff line Loading @@ -32,9 +32,7 @@ abstract class BaseFlags { // Custom flags go below this public static boolean LAUNCHER3_DISABLE_ICON_NORMALIZATION = false; public static boolean LAUNCHER3_LEGACY_FOLDER_ICON = false; public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false; public static boolean LAUNCHER3_NEW_FOLDER_ANIMATION = true; // When enabled allows to use any point on the fast scrollbar to start dragging. public static final boolean LAUNCHER3_DIRECT_SCROLL = true; // When enabled while all-apps open, the soft input will be set to adjust resize . Loading
src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java +10 −41 Original line number Diff line number Diff line package com.android.launcher3.folder; public class ClippedFolderIconLayoutRule { public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule { static final int MAX_NUM_ITEMS_IN_PREVIEW = 4; public static final int MAX_NUM_ITEMS_IN_PREVIEW = 4; private static final int MIN_NUM_ITEMS_IN_PREVIEW = 2; private static final float MIN_SCALE = 0.48f; Loading @@ -11,8 +10,8 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule 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; public static final int EXIT_INDEX = -2; public static final int ENTER_INDEX = -3; private float[] mTmpPoint = new float[2]; Loading @@ -22,7 +21,6 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule private boolean mIsRtl; private float mBaselineIconScale; @Override public void init(int availableSpace, float intrinsicIconSize, boolean rtl) { mAvailableSpace = availableSpace; mRadius = ITEM_RADIUS_SCALE_FACTOR * availableSpace / 2f; Loading @@ -31,19 +29,18 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule mBaselineIconScale = availableSpace / (intrinsicIconSize * 1f); } @Override public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, PreviewItemDrawingParams params) { float totalScale = scaleForItem(index, curNumItems); float totalScale = scaleForItem(curNumItems); float transX; float transY; float overlayAlpha = 0; if (index == getExitIndex()) { if (index == EXIT_INDEX) { // 0 1 * <-- Exit position (row 0, col 2) // 2 3 getGridPosition(0, 2, mTmpPoint); } else if (index == getEnterIndex()) { } else if (index == ENTER_INDEX) { // 0 1 // 2 3 * <-- Enter position (row 1, col 2) getGridPosition(1, 2, mTmpPoint); Loading Loading @@ -120,7 +117,7 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule MIN_NUM_ITEMS_IN_PREVIEW) / (MAX_NUM_ITEMS_IN_PREVIEW - MIN_NUM_ITEMS_IN_PREVIEW)); double theta = theta0 + index * (2 * Math.PI / curNumItems) * direction; float halfIconSize = (mIconSize * scaleForItem(index, curNumItems)) / 2; float halfIconSize = (mIconSize * scaleForItem(curNumItems)) / 2; // Map the location along the circle, and offset the coordinates to represent the center // of the icon, and to be based from the top / left of the preview area. The y component Loading @@ -130,10 +127,9 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule } @Override public float scaleForItem(int index, int numItems) { public float scaleForItem(int numItems) { // Scale is determined by the number of items in the preview. float scale = 1f; final float scale; if (numItems <= 2) { scale = MAX_SCALE; } else if (numItems == 3) { Loading @@ -141,37 +137,10 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule } else { scale = MIN_SCALE; } return scale * mBaselineIconScale; } @Override public float getIconSize() { return mIconSize; } @Override public int maxNumItems() { return MAX_NUM_ITEMS_IN_PREVIEW; } @Override 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; } }
src/com/android/launcher3/folder/Folder.java +15 −137 Original line number Diff line number Diff line Loading @@ -19,8 +19,6 @@ package com.android.launcher3.folder; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; Loading @@ -37,7 +35,6 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewDebug; import android.view.accessibility.AccessibilityEvent; import android.view.animation.AccelerateInterpolator; import android.view.animation.AnimationUtils; import android.view.inputmethod.EditorInfo; import android.widget.TextView; Loading @@ -55,9 +52,7 @@ import com.android.launcher3.FolderInfo; import com.android.launcher3.FolderInfo.FolderListener; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LogDecelerateInterpolator; import com.android.launcher3.OnAlarmListener; import com.android.launcher3.PagedView; import com.android.launcher3.R; Loading @@ -66,8 +61,6 @@ import com.android.launcher3.UninstallDropTarget.DropTargetSource; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace.ItemOperator; import com.android.launcher3.accessibility.AccessibleDragListenerAdapter; import com.android.launcher3.anim.AnimationLayerSet; import com.android.launcher3.anim.CircleRevealOutlineProvider; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragController.DragListener; Loading Loading @@ -137,10 +130,6 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC private AnimatorSet mCurrentAnimator; private final int mExpandDuration; public final int mMaterialExpandDuration; private final int mMaterialExpandStagger; protected final Launcher mLauncher; protected DragController mDragController; public FolderInfo mInfo; Loading Loading @@ -201,9 +190,6 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC super(context, attrs); setAlwaysDrawnWithCacheEnabled(false); Resources res = getResources(); mExpandDuration = res.getInteger(R.integer.config_folderExpandDuration); mMaterialExpandDuration = res.getInteger(R.integer.config_materialFolderExpandDuration); mMaterialExpandStagger = res.getInteger(R.integer.config_materialFolderExpandStagger); if (sDefaultFolderName == null) { sDefaultFolderName = res.getString(R.string.folder_name); Loading Loading @@ -487,25 +473,6 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC ? R.layout.user_folder : R.layout.user_folder_icon_normalized, null); } /** * This method is intended to make the UserFolder to be visually identical in size and position * to its associated FolderIcon. This allows for a seamless transition into the expanded state. */ private void positionAndSizeAsIcon() { if (!(getParent() instanceof DragLayer)) return; setScaleX(0.8f); setScaleY(0.8f); setAlpha(0f); mState = STATE_SMALL; } private void prepareReveal() { setScaleX(1f); setScaleY(1f); setAlpha(1f); mState = STATE_SMALL; } private void startAnimation(final AnimatorSet a) { if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) { mCurrentAnimator.cancel(); Loading @@ -525,61 +492,6 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC a.start(); } private AnimatorSet getOpeningAnimator() { prepareReveal(); mFolderIcon.growAndFadeOut(); AnimatorSet anim = LauncherAnimUtils.createAnimatorSet(); int width = getFolderWidth(); int height = getFolderHeight(); float transX = - 0.075f * (width / 2 - getPivotX()); float transY = - 0.075f * (height / 2 - getPivotY()); setTranslationX(transX); setTranslationY(transY); PropertyValuesHolder tx = PropertyValuesHolder.ofFloat(TRANSLATION_X, transX, 0); PropertyValuesHolder ty = PropertyValuesHolder.ofFloat(TRANSLATION_Y, transY, 0); Animator drift = ObjectAnimator.ofPropertyValuesHolder(this, tx, ty); drift.setDuration(mMaterialExpandDuration); drift.setStartDelay(mMaterialExpandStagger); drift.setInterpolator(new LogDecelerateInterpolator(100, 0)); int rx = (int) Math.max(Math.max(width - getPivotX(), 0), getPivotX()); int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY()); float radius = (float) Math.hypot(rx, ry); Animator reveal = new CircleRevealOutlineProvider((int) getPivotX(), (int) getPivotY(), 0, radius).createRevealAnimator(this); reveal.setDuration(mMaterialExpandDuration); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); mContent.setAlpha(0f); Animator iconsAlpha = ObjectAnimator.ofFloat(mContent, "alpha", 0f, 1f); iconsAlpha.setDuration(mMaterialExpandDuration); iconsAlpha.setStartDelay(mMaterialExpandStagger); iconsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); mFooter.setAlpha(0f); Animator textAlpha = ObjectAnimator.ofFloat(mFooter, "alpha", 0f, 1f); textAlpha.setDuration(mMaterialExpandDuration); textAlpha.setStartDelay(mMaterialExpandStagger); textAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); anim.play(drift); anim.play(iconsAlpha); anim.play(textAlpha); anim.play(reveal); AnimationLayerSet layerSet = new AnimationLayerSet(); layerSet.addView(mContent); layerSet.addView(mFooter); anim.addListener(layerSet); return anim; } /** * Opens the user folder described by the specified tag. The opening of the folder * is animated relative to the specified View. If the View is null, no animation Loading Loading @@ -621,9 +533,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC final Runnable onCompleteRunnable; centerAboutIcon(); AnimatorSet anim = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION ? new FolderAnimationManager(this, true /* isOpening */).getAnimator() : getOpeningAnimator(); AnimatorSet anim = new FolderAnimationManager(this, true /* isOpening */).getAnimator(); onCompleteRunnable = new Runnable() { @Override public void run() { Loading @@ -633,12 +543,8 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { mFolderIcon.setBackgroundVisible(false); mFolderIcon.drawLeaveBehindIfExists(); } else { mFolderIcon.setVisibility(INVISIBLE); } Utilities.sendCustomAccessibilityEvent( Folder.this, Loading Loading @@ -728,11 +634,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC } if (mFolderIcon != null) { if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { mFolderIcon.clearLeaveBehindIfExists(); } else { mFolderIcon.shrinkAndFadeIn(animate); } } if (!(getParent() instanceof DragLayer)) return; Loading @@ -749,21 +651,8 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC parent.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } private AnimatorSet getClosingAnimator() { AnimatorSet animatorSet = LauncherAnimUtils.createAnimatorSet(); animatorSet.play(LauncherAnimUtils.ofViewAlphaAndScale(this, 0, 0.9f, 0.9f)); AnimationLayerSet layerSet = new AnimationLayerSet(); layerSet.addView(this); animatorSet.addListener(layerSet); animatorSet.setDuration(mExpandDuration); return animatorSet; } private void animateClosed() { AnimatorSet a = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION ? new FolderAnimationManager(this, false /* isOpening */).getAnimator() : getClosingAnimator(); AnimatorSet a = new FolderAnimationManager(this, false /* isOpening */).getAnimator(); a.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Loading @@ -790,16 +679,12 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC clearFocus(); if (mFolderIcon != null) { mFolderIcon.setVisibility(View.VISIBLE); if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { mFolderIcon.setBackgroundVisible(true); mFolderIcon.mFolderName.setTextVisibility(true); } if (wasAnimated) { if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { mFolderIcon.mBackground.fadeInBackgroundShadow(); mFolderIcon.mBackground.animateBackgroundStroke(); mFolderIcon.onFolderClose(mContent.getCurrentPage()); } if (mFolderIcon.hasBadge()) { mFolderIcon.createBadgeScaleAnimator(0f, 1f).start(); } Loading Loading @@ -852,18 +737,14 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC return (getLayoutDirection() == LAYOUT_DIRECTION_RTL); } @Override public void onDragOver(DragObject d) { onDragOver(d, REORDER_DELAY); } private int getTargetRank(DragObject d, float[] recycle) { recycle = d.getVisualCenter(recycle); return mContent.findNearestArea( (int) recycle[0] - getPaddingLeft(), (int) recycle[1] - getPaddingTop()); } @Thunk void onDragOver(DragObject d, int reorderDelay) { @Override public void onDragOver(DragObject d) { if (mScrollPauseAlarm.alarmPending()) { return; } Loading Loading @@ -1095,11 +976,8 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC } public boolean isDropEnabled() { if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) { return mState != STATE_ANIMATING; } return true; } public boolean isFull() { return mContent.isFull(); Loading @@ -1113,7 +991,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC int width = getFolderWidth(); int height = getFolderHeight(); float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, sTempRect); parent.getDescendantRectRelativeToSelf(mFolderIcon, sTempRect); int centerX = sTempRect.centerX(); int centerY = sTempRect.centerY(); int centeredLeft = centerX - width / 2; Loading Loading @@ -1611,7 +1489,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC @Override public void onAlarm(Alarm alarm) { // Reorder immediately on page change. onDragOver(mDragObject, 1); onDragOver(mDragObject); } } Loading
src/com/android/launcher3/folder/FolderAnimationManager.java +13 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.content.Context; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.GradientDrawable; Loading @@ -44,6 +45,8 @@ import com.android.launcher3.util.Themes; import java.util.List; import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW; /** * Manages the opening and closing animations for a {@link Folder}. * Loading Loading @@ -101,8 +104,9 @@ public class FolderAnimationManager { mIsOpening = isOpening; mDuration = mFolder.mMaterialExpandDuration; mDelay = mContext.getResources().getInteger(R.integer.config_folderDelay); Resources res = mContent.getResources(); mDuration = res.getInteger(R.integer.config_materialFolderExpandDuration); mDelay = res.getInteger(R.integer.config_folderDelay); mFolderInterpolator = AnimationUtils.loadInterpolator(mContext, R.interpolator.folder_interpolator); Loading @@ -118,7 +122,7 @@ public class FolderAnimationManager { */ public AnimatorSet getAnimator() { final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) mFolder.getLayoutParams(); FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule(); ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule(); final List<BubbleTextView> itemsInPreview = mFolderIcon.getPreviewItems(); // Match position of the FolderIcon Loading @@ -129,7 +133,7 @@ public class FolderAnimationManager { float initialSize = (scaledRadius * 2) * scaleRelativeToDragLayer; // Match size/scale of icons in the preview float previewScale = rule.scaleForItem(0, itemsInPreview.size()); float previewScale = rule.scaleForItem(itemsInPreview.size()); float previewSize = rule.getIconSize() * previewScale; float initialScale = previewSize / itemsInPreview.get(0).getIconSize() * scaleRelativeToDragLayer; Loading Loading @@ -242,15 +246,14 @@ public class FolderAnimationManager { */ private void addPreviewItemAnimators(AnimatorSet animatorSet, final float folderScale, int previewItemOffsetX, int previewItemOffsetY) { FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule(); ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule(); 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; ? numItemsInPreview : MAX_NUM_ITEMS_IN_PREVIEW; TimeInterpolator previewItemInterpolator = getPreviewItemInterpolator(); Loading @@ -264,7 +267,7 @@ public class FolderAnimationManager { cwc.setupLp(btv); // Match scale of icons in the preview of the items on the first page. float previewScale = rule.scaleForItem(i, numItemsInFirstPagePreview); float previewScale = rule.scaleForItem(numItemsInFirstPagePreview); float previewSize = rule.getIconSize() * previewScale; float iconScale = previewSize / itemsInPreview.get(i).getIconSize(); Loading Loading @@ -299,7 +302,7 @@ public class FolderAnimationManager { scaleAnimator.setInterpolator(previewItemInterpolator); play(animatorSet, scaleAnimator); if (mFolder.getItemCount() > FolderIcon.NUM_ITEMS_IN_PREVIEW) { if (mFolder.getItemCount() > MAX_NUM_ITEMS_IN_PREVIEW) { // These delays allows the preview items to move as part of the Folder's motion, // and its only necessary for large folders because of differing interpolators. int delay = mIsOpening ? mDelay : mDelay * 2; Loading Loading @@ -349,7 +352,7 @@ public class FolderAnimationManager { } private TimeInterpolator getPreviewItemInterpolator() { if (mFolder.getItemCount() > FolderIcon.NUM_ITEMS_IN_PREVIEW) { if (mFolder.getItemCount() > MAX_NUM_ITEMS_IN_PREVIEW) { // With larger folders, we want the preview items to reach their final positions faster // (when opening) and later (when closing) so that they appear aligned with the rest of // the folder items when they are both visible. Loading