diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java | 100 |
1 files changed, 71 insertions, 29 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 015079ff900a..e06ae6992165 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -49,6 +49,7 @@ import android.graphics.RectF; import android.graphics.Region; import android.graphics.drawable.TransitionDrawable; import android.os.Bundle; +import android.os.Handler; import android.provider.Settings; import android.util.Log; import android.view.Choreographer; @@ -160,6 +161,12 @@ public class BubbleStackView extends FrameLayout SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_NO_BOUNCY); /** + * Handler to use for all delayed animations - this way, we can easily cancel them before + * starting a new animation. + */ + private final Handler mDelayedAnimationHandler = new Handler(); + + /** * Interface to synchronize {@link View} state and the screen. * * {@hide} @@ -293,6 +300,7 @@ public class BubbleStackView extends FrameLayout private boolean mViewUpdatedRequested = false; private boolean mIsExpansionAnimating = false; + private boolean mIsBubbleSwitchAnimating = false; private boolean mShowingDismiss = false; /** The view to desaturate/darken when magneted to the dismiss target. */ @@ -470,6 +478,13 @@ public class BubbleStackView extends FrameLayout private OnClickListener mBubbleClickListener = new OnClickListener() { @Override public void onClick(View view) { + // Bubble clicks either trigger expansion/collapse or a bubble switch, both of which we + // shouldn't interrupt. These are quick transitions, so it's not worth trying to adjust + // the animations inflight. + if (mIsExpansionAnimating || mIsBubbleSwitchAnimating) { + return; + } + final Bubble clickedBubble = mBubbleData.getBubbleWithView(view); // If the bubble has since left us, ignore the click. @@ -1730,6 +1745,8 @@ public class BubbleStackView extends FrameLayout } private void animateExpansion() { + cancelDelayedExpandCollapseSwitchAnimations(); + mIsExpanded = true; hideStackUserEducation(true /* fromExpansion */); beforeExpandedViewAnimation(); @@ -1778,37 +1795,43 @@ public class BubbleStackView extends FrameLayout mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); } - postDelayed(() -> PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) - .spring(AnimatableScaleMatrix.SCALE_X, - AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f), - mScaleInSpringConfig) - .spring(AnimatableScaleMatrix.SCALE_Y, - AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f), - mScaleInSpringConfig) - .addUpdateListener((target, values) -> { - if (mExpandedBubble.getIconView() == null) { - return; - } - mExpandedViewContainerMatrix.postTranslate( - mExpandedBubble.getIconView().getTranslationX() - - bubbleWillBeAtX, - 0); - mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); - }) - .withEndActions(() -> { - if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { - mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); - } - }) - .start(), startDelay); - + mDelayedAnimationHandler.postDelayed(() -> + PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) + .spring(AnimatableScaleMatrix.SCALE_X, + AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f), + mScaleInSpringConfig) + .spring(AnimatableScaleMatrix.SCALE_Y, + AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f), + mScaleInSpringConfig) + .addUpdateListener((target, values) -> { + if (mExpandedBubble.getIconView() == null) { + return; + } + mExpandedViewContainerMatrix.postTranslate( + mExpandedBubble.getIconView().getTranslationX() + - bubbleWillBeAtX, + 0); + mExpandedViewContainer.setAnimationMatrix( + mExpandedViewContainerMatrix); + }) + .withEndActions(() -> { + if (mExpandedBubble != null + && mExpandedBubble.getExpandedView() != null) { + mExpandedBubble.getExpandedView() + .setSurfaceZOrderedOnTop(false); + } + }) + .start(), startDelay); } private void animateCollapse() { + cancelDelayedExpandCollapseSwitchAnimations(); + // Hide the menu if it's visible. showManageMenu(false); mIsExpanded = false; + mIsExpansionAnimating = true; mBubbleContainer.cancelAllAnimations(); @@ -1824,12 +1847,10 @@ public class BubbleStackView extends FrameLayout final long startDelay = (long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 0.6f); - postDelayed(() -> mExpandedAnimationController.collapseBackToStack( + mDelayedAnimationHandler.postDelayed(() -> mExpandedAnimationController.collapseBackToStack( mStackAnimationController.getStackPositionAlongNearestHorizontalEdge() /* collapseTo */, - () -> { - mBubbleContainer.setActiveController(mStackAnimationController); - }), startDelay); + () -> mBubbleContainer.setActiveController(mStackAnimationController)), startDelay); // We want to visually collapse into this bubble during the animation. final View expandingFromBubble = mExpandedBubble.getIconView(); @@ -1884,6 +1905,13 @@ public class BubbleStackView extends FrameLayout } private void animateSwitchBubbles() { + // If we're no longer expanded, this is meaningless. + if (!mIsExpanded) { + return; + } + + mIsBubbleSwitchAnimating = true; + // The surface contains a screenshot of the animating out bubble, so we just need to animate // it out (and then release the GraphicBuffer). PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer).cancel(); @@ -1909,8 +1937,9 @@ public class BubbleStackView extends FrameLayout 0f, 0f, expandingFromBubbleDestinationX + mBubbleSize / 2f, getExpandedViewY()); mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); - mExpandedViewContainer.postDelayed(() -> { + mDelayedAnimationHandler.postDelayed(() -> { if (!mIsExpanded) { + mIsBubbleSwitchAnimating = false; return; } @@ -1928,11 +1957,24 @@ public class BubbleStackView extends FrameLayout if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); } + + mIsBubbleSwitchAnimating = false; }) .start(); }, 25); } + /** + * Cancels any delayed steps for expand/collapse and bubble switch animations, and resets the is + * animating flags for those animations. + */ + private void cancelDelayedExpandCollapseSwitchAnimations() { + mDelayedAnimationHandler.removeCallbacksAndMessages(null); + + mIsExpansionAnimating = false; + mIsBubbleSwitchAnimating = false; + } + private void notifyExpansionChanged(BubbleViewProvider bubble, boolean expanded) { if (mExpandListener != null && bubble != null) { mExpandListener.onBubbleExpandChanged(expanded, bubble.getKey()); |