diff options
author | Tony Wickham <twickham@google.com> | 2016-08-03 20:09:44 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-08-03 20:09:44 +0000 |
commit | f0cb6018dd7d91e58d2e9513f63ce7e2710c85d3 (patch) | |
tree | dfb2e212867a6e71fed5d0b16943a5eac33666ec | |
parent | 7b6e3aea315dd9a73890234d00df1afe277b2c68 (diff) | |
parent | 0ba81607e30c008a7aa24ca76d74f9c4aaafd053 (diff) | |
download | android_packages_apps_Trebuchet-f0cb6018dd7d91e58d2e9513f63ce7e2710c85d3.tar.gz android_packages_apps_Trebuchet-f0cb6018dd7d91e58d2e9513f63ce7e2710c85d3.tar.bz2 android_packages_apps_Trebuchet-f0cb6018dd7d91e58d2e9513f63ce7e2710c85d3.zip |
Merge "Start shortcuts close animation where open left off." into ub-launcher3-calgary
3 files changed, 89 insertions, 25 deletions
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java index b651f255b..37b6d0422 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java @@ -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; @@ -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; @@ -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(); @@ -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); @@ -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; } /** @@ -113,7 +143,7 @@ public class DeepShortcutView extends FrameLayout { int iconCenterX = getIconCenter().x; return new PillWidthRevealOutlineProvider(mPillRect, iconCenterX - halfHeight, iconCenterX + halfHeight) - .createRevealAnimator(this, true); + .createRevealAnimator(this, true); } /** @@ -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; + } + } } diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java index 3d1bee59d..a341b973c 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java @@ -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; @@ -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) { @@ -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(); @@ -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; } } diff --git a/src/com/android/launcher3/util/RevealOutlineAnimation.java b/src/com/android/launcher3/util/RevealOutlineAnimation.java index cd9888232..456047775 100644 --- a/src/com/android/launcher3/util/RevealOutlineAnimation.java +++ b/src/com/android/launcher3/util/RevealOutlineAnimation.java @@ -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); @@ -46,11 +48,18 @@ public abstract class RevealOutlineAnimation extends ViewOutlineProvider { } } + @Override + public void onAnimationCancel(Animator animation) { + mWasCanceled = true; + } + public void onAnimationEnd(Animator animation) { - revealView.setOutlineProvider(ViewOutlineProvider.BACKGROUND); - revealView.setClipToOutline(false); - if (shouldRemoveElevationDuringAnimation()) { - revealView.setTranslationZ(0); + if (!mWasCanceled) { + revealView.setOutlineProvider(ViewOutlineProvider.BACKGROUND); + revealView.setClipToOutline(false); + if (shouldRemoveElevationDuringAnimation()) { + revealView.setTranslationZ(0); + } } } |