summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java155
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java54
2 files changed, 103 insertions, 106 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index b68b7627fe8c..31cf853dce04 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -169,7 +169,7 @@ public class BubbleStackView extends FrameLayout {
* Callback to run after the flyout hides. Also called if a new flyout is shown before the
* previous one animates out.
*/
- private Runnable mAfterFlyoutHides;
+ private Runnable mFlyoutOnHide;
/** Layout change listener that moves the stack to the nearest valid position on rotation. */
private OnLayoutChangeListener mOrientationChangedListener;
@@ -1401,111 +1401,106 @@ public class BubbleStackView extends FrameLayout {
@VisibleForTesting
void animateInFlyoutForBubble(Bubble bubble) {
final CharSequence updateMessage = bubble.getUpdateMessage(getContext());
-
if (!bubble.showFlyoutForBubble()) {
// In case flyout was suppressed for this update, reset now.
bubble.setSuppressFlyout(false);
return;
}
-
if (updateMessage == null
|| isExpanded()
|| mIsExpansionAnimating
|| mIsGestureInProgress
- || mBubbleToExpandAfterFlyoutCollapse != null) {
+ || mBubbleToExpandAfterFlyoutCollapse != null
+ || bubble.getIconView() == null) {
// Skip the message if none exists, we're expanded or animating expansion, or we're
- // about to expand a bubble from the previous tapped flyout.
+ // about to expand a bubble from the previous tapped flyout, or if bubble view is null.
return;
}
-
- if (bubble.getIconView() != null) {
- // Temporarily suppress the dot while the flyout is visible.
- bubble.getIconView().setSuppressDot(
- true /* suppressDot */, false /* animate */);
-
- mFlyout.removeCallbacks(mAnimateInFlyout);
- mFlyoutDragDeltaX = 0f;
-
- if (mAfterFlyoutHides != null) {
- mAfterFlyoutHides.run();
+ mFlyoutDragDeltaX = 0f;
+ clearFlyoutOnHide();
+ mFlyoutOnHide = () -> {
+ resetDot(bubble);
+ if (mBubbleToExpandAfterFlyoutCollapse == null) {
+ return;
}
-
- mAfterFlyoutHides = () -> {
- final boolean suppressDot = !bubble.showBubbleDot();
- // If we're going to suppress the dot, make it visible first so it'll
- // visibly animate away.
- if (suppressDot) {
- bubble.getIconView().setSuppressDot(
- false /* suppressDot */, false /* animate */);
- }
- // Reset dot suppression. If we're not suppressing due to DND, then
- // stop suppressing it with no animation (since the flyout has
- // transformed into the dot). If we are suppressing due to DND, animate
- // it away.
- bubble.getIconView().setSuppressDot(
- suppressDot /* suppressDot */,
- suppressDot /* animate */);
-
- if (mBubbleToExpandAfterFlyoutCollapse != null) {
- mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
- mBubbleData.setExpanded(true);
- mBubbleToExpandAfterFlyoutCollapse = null;
- }
- };
-
- mFlyout.setVisibility(INVISIBLE);
-
- // Post in case layout isn't complete and getWidth returns 0.
- post(() -> {
- // An auto-expanding bubble could have been posted during the time it takes to
- // layout.
- if (isExpanded()) {
- return;
- }
-
- final Runnable afterShow = () -> {
- mAnimateInFlyout = () -> {
- mFlyout.setVisibility(VISIBLE);
- bubble.getIconView().setSuppressDot(
- true /* suppressDot */, false /* animate */);
- mFlyoutDragDeltaX =
- mStackAnimationController.isStackOnLeftSide()
- ? -mFlyout.getWidth()
- : mFlyout.getWidth();
- animateFlyoutCollapsed(false /* collapsed */, 0 /* velX */);
- mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
- };
-
- mFlyout.postDelayed(mAnimateInFlyout, 200);
+ mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
+ mBubbleData.setExpanded(true);
+ mBubbleToExpandAfterFlyoutCollapse = null;
+ };
+ mFlyout.setVisibility(INVISIBLE);
+
+ // Temporarily suppress the dot while the flyout is visible.
+ bubble.getIconView().setSuppressDot(
+ true /* suppressDot */, false /* animate */);
+
+ // Start flyout expansion. Post in case layout isn't complete and getWidth returns 0.
+ post(() -> {
+ // An auto-expanding bubble could have been posted during the time it takes to
+ // layout.
+ if (isExpanded()) {
+ return;
+ }
+ final Runnable expandFlyoutAfterDelay = () -> {
+ mAnimateInFlyout = () -> {
+ mFlyout.setVisibility(VISIBLE);
+ mFlyoutDragDeltaX =
+ mStackAnimationController.isStackOnLeftSide()
+ ? -mFlyout.getWidth()
+ : mFlyout.getWidth();
+ animateFlyoutCollapsed(false /* collapsed */, 0 /* velX */);
+ mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
};
-
- mFlyout.setupFlyoutStartingAsDot(
- updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
- mStackAnimationController.isStackOnLeftSide(),
- bubble.getIconView().getBadgeColor(),
- afterShow,
- mAfterFlyoutHides,
- bubble.getIconView().getDotCenter());
- mFlyout.bringToFront();
- });
- }
-
+ mFlyout.postDelayed(mAnimateInFlyout, 200);
+ };
+ mFlyout.setupFlyoutStartingAsDot(
+ updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
+ mStackAnimationController.isStackOnLeftSide(),
+ bubble.getIconView().getBadgeColor() /* dotColor */,
+ expandFlyoutAfterDelay /* onLayoutComplete */,
+ mFlyoutOnHide,
+ bubble.getIconView().getDotCenter());
+ mFlyout.bringToFront();
+ });
mFlyout.removeCallbacks(mHideFlyout);
mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
}
- /** Hide the flyout immediately and cancel any pending hide runnables. */
- private void hideFlyoutImmediate() {
- if (mAfterFlyoutHides != null) {
- mAfterFlyoutHides.run();
+ private void resetDot(Bubble bubble) {
+ final boolean suppressDot = !bubble.showBubbleDot();
+ // If we're going to suppress the dot, make it visible first so it'll
+ // visibly animate away.
+
+ if (suppressDot) {
+ bubble.getIconView().setSuppressDot(
+ false /* suppressDot */, false /* animate */);
}
+ // Reset dot suppression. If we're not suppressing due to DND, then
+ // stop suppressing it with no animation (since the flyout has
+ // transformed into the dot). If we are suppressing due to DND, animate
+ // it away.
+ bubble.getIconView().setSuppressDot(
+ suppressDot /* suppressDot */,
+ suppressDot /* animate */);
+ }
+ /** Hide the flyout immediately and cancel any pending hide runnables. */
+ private void hideFlyoutImmediate() {
+ clearFlyoutOnHide();
mFlyout.removeCallbacks(mAnimateInFlyout);
mFlyout.removeCallbacks(mHideFlyout);
mFlyout.hideFlyout();
}
+ private void clearFlyoutOnHide() {
+ mFlyout.removeCallbacks(mAnimateInFlyout);
+ if (mFlyoutOnHide == null) {
+ return;
+ }
+ mFlyoutOnHide.run();
+ mFlyoutOnHide = null;
+ }
+
@Override
public void getBoundsOnScreen(Rect outRect) {
if (!mIsExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
index 603c4169c169..4512aa822e3b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
@@ -61,7 +61,7 @@ public class BubbleView extends FrameLayout {
// mBubbleIconFactory cannot be static because it depends on Context.
private BubbleIconFactory mBubbleIconFactory;
- private boolean mSuppressDot = false;
+ private boolean mSuppressDot;
private Bubble mBubble;
@@ -140,6 +140,7 @@ public class BubbleView extends FrameLayout {
public void setAppIcon(Drawable appIcon) {
mUserBadgedAppIcon = appIcon;
}
+
/**
* @return the {@link ExpandableNotificationRow} view to display notification content when the
* bubble is expanded.
@@ -154,7 +155,6 @@ public class BubbleView extends FrameLayout {
updateDotVisibility(animate, null /* after */);
}
-
/**
* Sets whether or not to hide the dot even if we'd otherwise show it. This is used while the
* flyout is visible or animating, to hide the dot until the flyout visually transforms into it.
@@ -166,7 +166,7 @@ public class BubbleView extends FrameLayout {
/** Sets the position of the 'new' dot, animating it out and back in if requested. */
void setDotPosition(boolean onLeft, boolean animate) {
- if (animate && onLeft != mBadgedImageView.getDotOnLeft() && !mSuppressDot) {
+ if (animate && onLeft != mBadgedImageView.getDotOnLeft() && shouldShowDot()) {
animateDot(false /* showDot */, () -> {
mBadgedImageView.setDotOnLeft(onLeft);
animateDot(true /* showDot */, null);
@@ -190,12 +190,12 @@ public class BubbleView extends FrameLayout {
* after animation if requested.
*/
private void updateDotVisibility(boolean animate, Runnable after) {
- boolean showDot = mBubble.showBubbleDot() && !mSuppressDot;
-
+ final boolean showDot = shouldShowDot();
if (animate) {
animateDot(showDot, after);
} else {
mBadgedImageView.setShowDot(showDot);
+ mBadgedImageView.setDotScale(showDot ? 1f : 0f);
}
}
@@ -203,27 +203,25 @@ public class BubbleView extends FrameLayout {
* Animates the badge to show or hide.
*/
private void animateDot(boolean showDot, Runnable after) {
- if (mBadgedImageView.isShowingDot() != showDot) {
- if (showDot) {
- mBadgedImageView.setShowDot(true);
- }
- mBadgedImageView.clearAnimation();
- mBadgedImageView.animate().setDuration(200)
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .setUpdateListener((valueAnimator) -> {
- float fraction = valueAnimator.getAnimatedFraction();
- fraction = showDot ? fraction : 1f - fraction;
- mBadgedImageView.setDotScale(fraction);
- }).withEndAction(() -> {
- if (!showDot) {
- mBadgedImageView.setShowDot(false);
- }
-
- if (after != null) {
- after.run();
- }
- }).start();
+ if (mBadgedImageView.isShowingDot() == showDot) {
+ return;
}
+ // Do NOT wait until after animation ends to setShowDot
+ // to avoid overriding more recent showDot states.
+ mBadgedImageView.setShowDot(showDot);
+ mBadgedImageView.clearAnimation();
+ mBadgedImageView.animate().setDuration(200)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .setUpdateListener((valueAnimator) -> {
+ float fraction = valueAnimator.getAnimatedFraction();
+ fraction = showDot ? fraction : 1f - fraction;
+ mBadgedImageView.setDotScale(fraction);
+ }).withEndAction(() -> {
+ mBadgedImageView.setDotScale(showDot ? 1f : 0f);
+ if (after != null) {
+ after.run();
+ }
+ }).start();
}
void updateViews() {
@@ -273,7 +271,11 @@ public class BubbleView extends FrameLayout {
iconPath.transform(matrix);
mBadgedImageView.drawDot(iconPath);
- animateDot(mBubble.showBubbleDot() /* showDot */, null /* after */);
+ animateDot(shouldShowDot(), null /* after */);
+ }
+
+ boolean shouldShowDot() {
+ return mBubble.showBubbleDot() && !mSuppressDot;
}
int getBadgeColor() {