Loading src/com/android/launcher3/shortcuts/DeepShortcutView.java +60 −8 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.launcher3.shortcuts; import android.animation.Animator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; Loading @@ -26,6 +27,7 @@ import android.widget.FrameLayout; import com.android.launcher3.IconCache; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LogAccelerateInterpolator; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; Loading @@ -36,7 +38,7 @@ import com.android.launcher3.util.PillWidthRevealOutlineProvider; * A {@link android.widget.FrameLayout} that contains a {@link DeepShortcutView}. * This lets us animate the DeepShortcutView (icon and text) separately from the background. */ public class DeepShortcutView extends FrameLayout { public class DeepShortcutView extends FrameLayout implements ValueAnimator.AnimatorUpdateListener { private static final Point sTempPoint = new Point(); Loading @@ -44,6 +46,7 @@ public class DeepShortcutView extends FrameLayout { private DeepShortcutTextView mBubbleText; private View mIconView; private float mOpenAnimationProgress; public DeepShortcutView(Context context) { this(context, null, 0); Loading Loading @@ -95,14 +98,41 @@ public class DeepShortcutView extends FrameLayout { } /** * Creates an animator to play when the shortcut container is being opened or closed. * Creates an animator to play when the shortcut container is being opened. */ public Animator createOpenCloseAnimation( boolean isContainerAboveIcon, boolean pivotLeft, boolean isReverse) { public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) { Point center = getIconCenter(); return new ZoomRevealOutlineProvider(center.x, center.y, mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft) .createRevealAnimator(this, isReverse); ValueAnimator openAnimator = new ZoomRevealOutlineProvider(center.x, center.y, mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft) .createRevealAnimator(this, false); mOpenAnimationProgress = 0f; openAnimator.addUpdateListener(this); return openAnimator; } @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { mOpenAnimationProgress = valueAnimator.getAnimatedFraction(); } public boolean isOpenOrOpening() { return mOpenAnimationProgress > 0; } /** * Creates an animator to play when the shortcut container is being closed. */ public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft, long duration) { Point center = getIconCenter(); ValueAnimator closeAnimator = new ZoomRevealOutlineProvider(center.x, center.y, mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft) .createRevealAnimator(this, true); // Scale down the duration and interpolator according to the progress // that the open animation was at when the close started. closeAnimator.setDuration((long) (duration * mOpenAnimationProgress)); closeAnimator.setInterpolator(new CloseInterpolator(mOpenAnimationProgress)); return closeAnimator; } /** Loading Loading @@ -168,4 +198,26 @@ public class DeepShortcutView extends FrameLayout { mTranslateView.setTranslationX(mTranslateX - pivotX); } } /** * An interpolator that reverses the current open animation progress. */ private static class CloseInterpolator extends LogAccelerateInterpolator { private float mStartProgress; private float mRemainingProgress; /** * @param openAnimationProgress The progress that the open interpolator ended at. */ public CloseInterpolator(float openAnimationProgress) { super(100, 0); mStartProgress = 1f - openAnimationProgress; mRemainingProgress = openAnimationProgress; } @Override public float getInterpolation(float v) { return mStartProgress + super.getInterpolation(v) * mRemainingProgress; } } } src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +16 −13 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherViewPropertyAnimator; import com.android.launcher3.LogAccelerateInterpolator; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; Loading Loading @@ -261,8 +260,7 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC final DeepShortcutView deepShortcutView = getShortcutAt(i); deepShortcutView.setVisibility(INVISIBLE); Animator anim = deepShortcutView.createOpenCloseAnimation( mIsAboveIcon, mIsLeftAligned, false); Animator anim = deepShortcutView.createOpenAnimation(mIsAboveIcon, mIsLeftAligned); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { Loading Loading @@ -631,24 +629,29 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC mLauncher.getDragController().removeDragListener(this); final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet(); final int numShortcuts = getShortcutCount(); final int shortcutCount = getShortcutCount(); int numOpenShortcuts = 0; for (int i = 0; i < shortcutCount; i++) { if (getShortcutAt(i).isOpenOrOpening()) { numOpenShortcuts++; } } final long duration = getResources().getInteger( R.integer.config_deepShortcutCloseDuration); final long stagger = getResources().getInteger( R.integer.config_deepShortcutCloseStagger); long arrowDelay = (numShortcuts - 1) * stagger + (duration * 4 / 6); int firstShortcutIndex = mIsAboveIcon ? (numShortcuts - 1) : 0; LogAccelerateInterpolator interpolator = new LogAccelerateInterpolator(100, 0); for (int i = 0; i < numShortcuts; i++) { long arrowDelay = (numOpenShortcuts - 1) * stagger + (duration * 4 / 6); int firstOpenShortcutIndex = mIsAboveIcon ? shortcutCount - numOpenShortcuts : 0; int shortcutWithArrowIndex = mIsAboveIcon ? (numOpenShortcuts - 1) : 0; for (int i = firstOpenShortcutIndex; i < firstOpenShortcutIndex + numOpenShortcuts; i++) { final DeepShortcutView view = getShortcutAt(i); Animator anim; if (view.willDrawIcon()) { anim = view.createOpenCloseAnimation(mIsAboveIcon, mIsLeftAligned, true); int animationIndex = mIsAboveIcon ? i : numShortcuts - i - 1; anim = view.createCloseAnimation(mIsAboveIcon, mIsLeftAligned, duration); int animationIndex = mIsAboveIcon ? i - firstOpenShortcutIndex : numOpenShortcuts - i - 1; anim.setStartDelay(stagger * animationIndex); anim.setDuration(duration); anim.setInterpolator(interpolator); } else { // The view is being dragged. Animate it such that it collapses with the drag view anim = view.collapseToIcon(); Loading @@ -668,7 +671,7 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC anim2.setDuration(DragView.VIEW_ZOOM_DURATION); shortcutAnims.play(anim2); if (i == firstShortcutIndex) { if (i == shortcutWithArrowIndex) { arrowDelay = 0; } } Loading src/com/android/launcher3/util/RevealOutlineAnimation.java +13 −4 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ public abstract class RevealOutlineAnimation extends ViewOutlineProvider { final float elevation = revealView.getElevation(); va.addListener(new AnimatorListenerAdapter() { private boolean mWasCanceled = false; public void onAnimationStart(Animator animation) { revealView.setOutlineProvider(RevealOutlineAnimation.this); revealView.setClipToOutline(true); Loading @@ -46,13 +48,20 @@ public abstract class RevealOutlineAnimation extends ViewOutlineProvider { } } @Override public void onAnimationCancel(Animator animation) { mWasCanceled = true; } public void onAnimationEnd(Animator animation) { if (!mWasCanceled) { revealView.setOutlineProvider(ViewOutlineProvider.BACKGROUND); revealView.setClipToOutline(false); if (shouldRemoveElevationDuringAnimation()) { revealView.setTranslationZ(0); } } } }); Loading Loading
src/com/android/launcher3/shortcuts/DeepShortcutView.java +60 −8 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.launcher3.shortcuts; import android.animation.Animator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; Loading @@ -26,6 +27,7 @@ import android.widget.FrameLayout; import com.android.launcher3.IconCache; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LogAccelerateInterpolator; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; Loading @@ -36,7 +38,7 @@ import com.android.launcher3.util.PillWidthRevealOutlineProvider; * A {@link android.widget.FrameLayout} that contains a {@link DeepShortcutView}. * This lets us animate the DeepShortcutView (icon and text) separately from the background. */ public class DeepShortcutView extends FrameLayout { public class DeepShortcutView extends FrameLayout implements ValueAnimator.AnimatorUpdateListener { private static final Point sTempPoint = new Point(); Loading @@ -44,6 +46,7 @@ public class DeepShortcutView extends FrameLayout { private DeepShortcutTextView mBubbleText; private View mIconView; private float mOpenAnimationProgress; public DeepShortcutView(Context context) { this(context, null, 0); Loading Loading @@ -95,14 +98,41 @@ public class DeepShortcutView extends FrameLayout { } /** * Creates an animator to play when the shortcut container is being opened or closed. * Creates an animator to play when the shortcut container is being opened. */ public Animator createOpenCloseAnimation( boolean isContainerAboveIcon, boolean pivotLeft, boolean isReverse) { public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) { Point center = getIconCenter(); return new ZoomRevealOutlineProvider(center.x, center.y, mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft) .createRevealAnimator(this, isReverse); ValueAnimator openAnimator = new ZoomRevealOutlineProvider(center.x, center.y, mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft) .createRevealAnimator(this, false); mOpenAnimationProgress = 0f; openAnimator.addUpdateListener(this); return openAnimator; } @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { mOpenAnimationProgress = valueAnimator.getAnimatedFraction(); } public boolean isOpenOrOpening() { return mOpenAnimationProgress > 0; } /** * Creates an animator to play when the shortcut container is being closed. */ public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft, long duration) { Point center = getIconCenter(); ValueAnimator closeAnimator = new ZoomRevealOutlineProvider(center.x, center.y, mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft) .createRevealAnimator(this, true); // Scale down the duration and interpolator according to the progress // that the open animation was at when the close started. closeAnimator.setDuration((long) (duration * mOpenAnimationProgress)); closeAnimator.setInterpolator(new CloseInterpolator(mOpenAnimationProgress)); return closeAnimator; } /** Loading Loading @@ -168,4 +198,26 @@ public class DeepShortcutView extends FrameLayout { mTranslateView.setTranslationX(mTranslateX - pivotX); } } /** * An interpolator that reverses the current open animation progress. */ private static class CloseInterpolator extends LogAccelerateInterpolator { private float mStartProgress; private float mRemainingProgress; /** * @param openAnimationProgress The progress that the open interpolator ended at. */ public CloseInterpolator(float openAnimationProgress) { super(100, 0); mStartProgress = 1f - openAnimationProgress; mRemainingProgress = openAnimationProgress; } @Override public float getInterpolation(float v) { return mStartProgress + super.getInterpolation(v) * mRemainingProgress; } } }
src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +16 −13 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherViewPropertyAnimator; import com.android.launcher3.LogAccelerateInterpolator; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; Loading Loading @@ -261,8 +260,7 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC final DeepShortcutView deepShortcutView = getShortcutAt(i); deepShortcutView.setVisibility(INVISIBLE); Animator anim = deepShortcutView.createOpenCloseAnimation( mIsAboveIcon, mIsLeftAligned, false); Animator anim = deepShortcutView.createOpenAnimation(mIsAboveIcon, mIsLeftAligned); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { Loading Loading @@ -631,24 +629,29 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC mLauncher.getDragController().removeDragListener(this); final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet(); final int numShortcuts = getShortcutCount(); final int shortcutCount = getShortcutCount(); int numOpenShortcuts = 0; for (int i = 0; i < shortcutCount; i++) { if (getShortcutAt(i).isOpenOrOpening()) { numOpenShortcuts++; } } final long duration = getResources().getInteger( R.integer.config_deepShortcutCloseDuration); final long stagger = getResources().getInteger( R.integer.config_deepShortcutCloseStagger); long arrowDelay = (numShortcuts - 1) * stagger + (duration * 4 / 6); int firstShortcutIndex = mIsAboveIcon ? (numShortcuts - 1) : 0; LogAccelerateInterpolator interpolator = new LogAccelerateInterpolator(100, 0); for (int i = 0; i < numShortcuts; i++) { long arrowDelay = (numOpenShortcuts - 1) * stagger + (duration * 4 / 6); int firstOpenShortcutIndex = mIsAboveIcon ? shortcutCount - numOpenShortcuts : 0; int shortcutWithArrowIndex = mIsAboveIcon ? (numOpenShortcuts - 1) : 0; for (int i = firstOpenShortcutIndex; i < firstOpenShortcutIndex + numOpenShortcuts; i++) { final DeepShortcutView view = getShortcutAt(i); Animator anim; if (view.willDrawIcon()) { anim = view.createOpenCloseAnimation(mIsAboveIcon, mIsLeftAligned, true); int animationIndex = mIsAboveIcon ? i : numShortcuts - i - 1; anim = view.createCloseAnimation(mIsAboveIcon, mIsLeftAligned, duration); int animationIndex = mIsAboveIcon ? i - firstOpenShortcutIndex : numOpenShortcuts - i - 1; anim.setStartDelay(stagger * animationIndex); anim.setDuration(duration); anim.setInterpolator(interpolator); } else { // The view is being dragged. Animate it such that it collapses with the drag view anim = view.collapseToIcon(); Loading @@ -668,7 +671,7 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC anim2.setDuration(DragView.VIEW_ZOOM_DURATION); shortcutAnims.play(anim2); if (i == firstShortcutIndex) { if (i == shortcutWithArrowIndex) { arrowDelay = 0; } } Loading
src/com/android/launcher3/util/RevealOutlineAnimation.java +13 −4 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ public abstract class RevealOutlineAnimation extends ViewOutlineProvider { final float elevation = revealView.getElevation(); va.addListener(new AnimatorListenerAdapter() { private boolean mWasCanceled = false; public void onAnimationStart(Animator animation) { revealView.setOutlineProvider(RevealOutlineAnimation.this); revealView.setClipToOutline(true); Loading @@ -46,13 +48,20 @@ public abstract class RevealOutlineAnimation extends ViewOutlineProvider { } } @Override public void onAnimationCancel(Animator animation) { mWasCanceled = true; } public void onAnimationEnd(Animator animation) { if (!mWasCanceled) { revealView.setOutlineProvider(ViewOutlineProvider.BACKGROUND); revealView.setClipToOutline(false); if (shouldRemoveElevationDuringAnimation()) { revealView.setTranslationZ(0); } } } }); Loading