Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +19 −3 Original line number Diff line number Diff line Loading @@ -802,16 +802,32 @@ public class BubbleController implements ConfigurationController.ConfigurationLi if (mStackView == null) { return; } if (mStatusBarStateListener.getCurrentState() == SHADE && hasBubbles()) { // Bubbles only appear in unlocked shade mStackView.setVisibility(hasBubbles() ? VISIBLE : INVISIBLE); } else if (mStackView != null) { } else if (!hasBubbles() && mStackView.hasTransientBubbles()) { // If we only have transient bubbles, then wait until they're gone. mStackView.runActionAfterTransientViewAnimations(() -> { mStackView.setVisibility(INVISIBLE); updateBubblesShowing(); }); } else { mStackView.setVisibility(INVISIBLE); } // Let listeners know if bubble state changed. updateBubblesShowing(); } /** * Updates the status bar window controller and the state change listener with whether bubbles * are currently showing. */ public void updateBubblesShowing() { boolean hadBubbles = mStatusBarWindowController.getBubblesShowing(); boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE; boolean hasBubblesShowing = (hasBubbles() || mStackView.hasTransientBubbles()) && mStackView.getVisibility() == VISIBLE; mStatusBarWindowController.setBubblesShowing(hasBubblesShowing); if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) { mStateChangeListener.onHasBubblesChanged(hasBubblesShowing); Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +8 −0 Original line number Diff line number Diff line Loading @@ -664,6 +664,10 @@ public class BubbleStackView extends FrameLayout { return mIsExpanded; } void runActionAfterTransientViewAnimations(Runnable after) { mStackAnimationController.runActionAfterAllViewsAndTransientRemoved(after); } /** * The {@link BubbleView} that is expanded, null if one does not exist. */ Loading Loading @@ -694,6 +698,10 @@ public class BubbleStackView extends FrameLayout { } } boolean hasTransientBubbles() { return mBubbleContainer.getTransientViewCount() > 0; } // via BubbleData.Listener void addBubble(Bubble bubble) { if (DEBUG_BUBBLE_STACK_VIEW) { Loading packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +32 −6 Original line number Diff line number Diff line Loading @@ -144,6 +144,11 @@ public class StackAnimationController extends */ private boolean mFirstBubbleSpringingToTouch = false; /** * Action to run after all views, including transient views, have been removed from the layout. */ @Nullable private Runnable mAfterAllViewsAndTransientRemoved = null; /** Horizontal offset of bubbles in the stack. */ private float mStackOffset; /** Diameter of the bubble icon. */ Loading Loading @@ -560,6 +565,14 @@ public class StackAnimationController extends }); } /** * Sets an action to run after all views, including transient views, have been removed from the * layout. */ public void runActionAfterAllViewsAndTransientRemoved(Runnable action) { mAfterAllViewsAndTransientRemoved = action; } /** * Springs the first bubble to the given final position, with the rest of the stack 'following'. */ Loading Loading @@ -647,13 +660,26 @@ public class StackAnimationController extends @Override void onChildRemoved(View child, int index, Runnable finishRemoval) { // Animate the removing view in the opposite direction of the stack. final float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X); animationForChild(child) .alpha(0f, finishRemoval /* after */) .scaleX(ANIMATE_IN_STARTING_SCALE) .scaleY(ANIMATE_IN_STARTING_SCALE) .translationX(mStackPosition.x - (-xOffset * ANIMATE_TRANSLATION_FACTOR)) .alpha(0f, finishRemoval /* after */, () -> { // If this was the last transient view, run the callback. if (mLayout.getTransientViewCount() == 0 && mAfterAllViewsAndTransientRemoved != null) { // If a 'real' view was added while we were animating out, don't run // the callback since all views haven't been removed. if (mLayout.getChildCount() == 0) { mAfterAllViewsAndTransientRemoved.run(); } mAfterAllViewsAndTransientRemoved = null; } } /* after */) .scaleX(0f) .scaleY(0f) .withStiffness(ANIMATE_IN_STIFFNESS) .start(); if (mLayout.getChildCount() > 0) { Loading Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +19 −3 Original line number Diff line number Diff line Loading @@ -802,16 +802,32 @@ public class BubbleController implements ConfigurationController.ConfigurationLi if (mStackView == null) { return; } if (mStatusBarStateListener.getCurrentState() == SHADE && hasBubbles()) { // Bubbles only appear in unlocked shade mStackView.setVisibility(hasBubbles() ? VISIBLE : INVISIBLE); } else if (mStackView != null) { } else if (!hasBubbles() && mStackView.hasTransientBubbles()) { // If we only have transient bubbles, then wait until they're gone. mStackView.runActionAfterTransientViewAnimations(() -> { mStackView.setVisibility(INVISIBLE); updateBubblesShowing(); }); } else { mStackView.setVisibility(INVISIBLE); } // Let listeners know if bubble state changed. updateBubblesShowing(); } /** * Updates the status bar window controller and the state change listener with whether bubbles * are currently showing. */ public void updateBubblesShowing() { boolean hadBubbles = mStatusBarWindowController.getBubblesShowing(); boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE; boolean hasBubblesShowing = (hasBubbles() || mStackView.hasTransientBubbles()) && mStackView.getVisibility() == VISIBLE; mStatusBarWindowController.setBubblesShowing(hasBubblesShowing); if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) { mStateChangeListener.onHasBubblesChanged(hasBubblesShowing); Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +8 −0 Original line number Diff line number Diff line Loading @@ -664,6 +664,10 @@ public class BubbleStackView extends FrameLayout { return mIsExpanded; } void runActionAfterTransientViewAnimations(Runnable after) { mStackAnimationController.runActionAfterAllViewsAndTransientRemoved(after); } /** * The {@link BubbleView} that is expanded, null if one does not exist. */ Loading Loading @@ -694,6 +698,10 @@ public class BubbleStackView extends FrameLayout { } } boolean hasTransientBubbles() { return mBubbleContainer.getTransientViewCount() > 0; } // via BubbleData.Listener void addBubble(Bubble bubble) { if (DEBUG_BUBBLE_STACK_VIEW) { Loading
packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +32 −6 Original line number Diff line number Diff line Loading @@ -144,6 +144,11 @@ public class StackAnimationController extends */ private boolean mFirstBubbleSpringingToTouch = false; /** * Action to run after all views, including transient views, have been removed from the layout. */ @Nullable private Runnable mAfterAllViewsAndTransientRemoved = null; /** Horizontal offset of bubbles in the stack. */ private float mStackOffset; /** Diameter of the bubble icon. */ Loading Loading @@ -560,6 +565,14 @@ public class StackAnimationController extends }); } /** * Sets an action to run after all views, including transient views, have been removed from the * layout. */ public void runActionAfterAllViewsAndTransientRemoved(Runnable action) { mAfterAllViewsAndTransientRemoved = action; } /** * Springs the first bubble to the given final position, with the rest of the stack 'following'. */ Loading Loading @@ -647,13 +660,26 @@ public class StackAnimationController extends @Override void onChildRemoved(View child, int index, Runnable finishRemoval) { // Animate the removing view in the opposite direction of the stack. final float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X); animationForChild(child) .alpha(0f, finishRemoval /* after */) .scaleX(ANIMATE_IN_STARTING_SCALE) .scaleY(ANIMATE_IN_STARTING_SCALE) .translationX(mStackPosition.x - (-xOffset * ANIMATE_TRANSLATION_FACTOR)) .alpha(0f, finishRemoval /* after */, () -> { // If this was the last transient view, run the callback. if (mLayout.getTransientViewCount() == 0 && mAfterAllViewsAndTransientRemoved != null) { // If a 'real' view was added while we were animating out, don't run // the callback since all views haven't been removed. if (mLayout.getChildCount() == 0) { mAfterAllViewsAndTransientRemoved.run(); } mAfterAllViewsAndTransientRemoved = null; } } /* after */) .scaleX(0f) .scaleY(0f) .withStiffness(ANIMATE_IN_STIFFNESS) .start(); if (mLayout.getChildCount() > 0) { Loading