diff options
| author | 2019-05-17 13:26:13 -0700 | |
|---|---|---|
| committer | 2019-05-24 11:24:02 -0700 | |
| commit | 522e9ff4ff37e2565b2716b20062b974035a1528 (patch) | |
| tree | 0eb60857707357cd6b5d770947ae5a841c64fd3e | |
| parent | 99885212fa371bca69da74416b18886f5fee8795 (diff) | |
Center-align bubble row
Center aligned bubbles change x position based on shown bubble count.
Update animations to reflect new behavior.
-On bubble add/remove
---Update pointer position
---Update all bubble positions
-New bubble x computation
---row left = screen center - half row width
---bubble left = row left + bubble index * space
Bug: 131849856
Test: manual
Change-Id: I9294c6831a648b01d16eef389e951585fd2fbde9
3 files changed, 115 insertions, 63 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index bec90d2edad1..04f8ce8a9529 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -237,16 +237,16 @@ public class BubbleStackView extends FrameLayout { private ViewClippingUtil.ClippingParameters mClippingParameters = new ViewClippingUtil.ClippingParameters() { - @Override - public boolean shouldFinish(View view) { - return false; - } + @Override + public boolean shouldFinish(View view) { + return false; + } - @Override - public boolean isClippingEnablingAllowed(View view) { - return !mIsExpanded; - } - }; + @Override + public boolean isClippingEnablingAllowed(View view) { + return !mIsExpanded; + } + }; /** Float property that 'drags' the flyout. */ private final FloatPropertyCompat mFlyoutCollapseProperty = @@ -288,7 +288,7 @@ public class BubbleStackView extends FrameLayout { private Runnable mAfterMagnet; public BubbleStackView(Context context, BubbleData data, - @Nullable SurfaceSynchronizer synchronizer) { + @Nullable SurfaceSynchronizer synchronizer) { super(context); mBubbleData = data; @@ -693,6 +693,7 @@ public class BubbleStackView extends FrameLayout { animateInFlyoutForBubble(bubble); requestUpdate(); logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__POSTED); + updatePointerPosition(); } // via BubbleData.Listener @@ -708,6 +709,7 @@ public class BubbleStackView extends FrameLayout { } else { Log.d(TAG, "was asked to remove Bubble, but didn't find the view! " + bubble); } + updatePointerPosition(); } // via BubbleData.Listener @@ -1067,8 +1069,8 @@ public class BubbleStackView extends FrameLayout { (overscrollingPastDot ? collapsePercent - 1f : collapsePercent * -1) * (overscrollingLeft ? -1 : 1) * (mFlyout.getWidth() / (FLYOUT_OVERSCROLL_ATTENUATION_FACTOR - // Attenuate the smaller dot less than the larger flyout. - / (overscrollingPastDot ? 2 : 1))); + // Attenuate the smaller dot less than the larger flyout. + / (overscrollingPastDot ? 2 : 1))); } mFlyout.setTranslationX(mFlyout.getRestingTranslationX() + overscrollTranslation); @@ -1470,18 +1472,22 @@ public class BubbleStackView extends FrameLayout { if (DEBUG) { Log.d(TAG, "updatePointerPosition()"); } - Bubble expandedBubble = getExpandedBubble(); - if (expandedBubble != null) { - BubbleView iconView = expandedBubble.iconView; - float bubbleLeft = iconView.getTranslationX(); - float halfBubbleWidth = (iconView.getWidth() / 2f); - // Bubbles live in expanded view container (x includes expanded view padding). - // Pointer lives in expanded view, which has padding (x does not include padding). - // Remove padding when deriving pointer location from bubbles. - float pointerX = bubbleLeft - mExpandedViewPadding + halfBubbleWidth; - expandedBubble.expandedView.setPointerPosition((int) pointerX); + Bubble expandedBubble = getExpandedBubble(); + if (expandedBubble == null) { + return; } + + int index = getBubbleIndex(expandedBubble); + float bubbleLeftFromScreenLeft = mExpandedAnimationController.getBubbleLeft(index); + float halfBubble = mBubbleSize / 2f; + + // Bubbles live in expanded view container (x includes expanded view padding). + // Pointer lives in expanded view, which has padding (x does not include padding). + // Remove padding when deriving pointer location from bubbles. + float bubbleCenter = bubbleLeftFromScreenLeft + halfBubble - mExpandedViewPadding; + + expandedBubble.expandedView.setPointerPosition(bubbleCenter); } /** diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index ae8043f86cdd..24337a3c3312 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -63,6 +63,8 @@ public class ExpandedAnimationController private Point mDisplaySize; /** Size of dismiss target at bottom of screen. */ private float mPipDismissHeight; + /** Max number of bubbles shown in row above expanded view.*/ + private int mBubblesMaxRendered; /** Whether the dragged-out bubble is in the dismiss target. */ private boolean mIndividualBubbleWithinDismissTarget = false; @@ -112,32 +114,25 @@ public class ExpandedAnimationController mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); mPipDismissHeight = res.getDimensionPixelSize(R.dimen.pip_dismiss_gradient_height); + mBubblesMaxRendered = res.getInteger(R.integer.bubbles_max_rendered); } /** * Animates expanding the bubbles into a row along the top of the screen. - * - * @return The y-value to which the bubbles were expanded, in case that's useful. */ - public float expandFromStack(PointF collapseTo, Runnable after) { + public void expandFromStack(PointF collapseTo, Runnable after) { animationsForChildrenFromIndex( 0, /* startIndex */ new ChildAnimationConfigurator() { - // How much to translate the next bubble, so that it is not overlapping the - // previous one. - float mTranslateNextBubbleXBy = mExpandedViewPadding + mBubblePaddingPx; - @Override public void configureAnimationForChildAtIndex( int index, PhysicsAnimationLayout.PhysicsPropertyAnimator animation) { - animation.position(mTranslateNextBubbleXBy, getExpandedY()); - mTranslateNextBubbleXBy += mBubbleSizePx + mBubblePaddingPx; + animation.position(getBubbleLeft(index), getExpandedY()); } }) .startAll(after); mCollapseToPoint = collapseTo; - return getExpandedY(); } /** Animate collapsing the bubbles back to their stacked position. */ @@ -189,9 +184,7 @@ public class ExpandedAnimationController final boolean draggedOutEnough = y > getExpandedY() + mBubbleSizePx || y < getExpandedY() - mBubbleSizePx; if (draggedOutEnough != mBubbleDraggedOutEnough) { - animateStackByBubbleWidthsStartingFrom( - /* numBubbleWidths */ draggedOutEnough ? -1 : 0, - /* startIndex */ mLayout.indexOfChild(bubbleView) + 1); + updateBubblePositions(); mBubbleDraggedOutEnough = draggedOutEnough; } } @@ -200,17 +193,14 @@ public class ExpandedAnimationController public void dismissDraggedOutBubble(Runnable after) { mIndividualBubbleWithinDismissTarget = false; - // Fill the space from the soon to be dismissed bubble. - animateStackByBubbleWidthsStartingFrom( - /* numBubbleWidths */ -1, - /* startIndex */ mLayout.indexOfChild(mBubbleDraggingOut) + 1); - animationForChild(mBubbleDraggingOut) .withStiffness(SpringForce.STIFFNESS_HIGH) .scaleX(1.1f) .scaleY(1.1f) .alpha(0f, after) .start(); + + updateBubblePositions(); } /** Magnets the given bubble to the dismiss target. */ @@ -251,15 +241,13 @@ public class ExpandedAnimationController final int index = mLayout.indexOfChild(bubbleView); animationForChildAtIndex(index) - .position(getXForChildAtIndex(index), getExpandedY()) - .withPositionStartVelocities(velX, velY) - .start(() -> bubbleView.setTranslationZ(0f) /* after */); - - animateStackByBubbleWidthsStartingFrom( - /* numBubbleWidths */ 0, /* startIndex */ index + 1); + .position(getBubbleLeft(index), getExpandedY()) + .withPositionStartVelocities(velX, velY) + .start(() -> bubbleView.setTranslationZ(0f) /* after */); mBubbleDraggingOut = null; mBubbleDraggedOutEnough = false; + updateBubblePositions(); } /** @@ -337,8 +325,6 @@ public class ExpandedAnimationController @Override void onChildAdded(View child, int index) { - // Pop in from the top. - // TODO: Reverse this when bubbles are at the bottom. child.setTranslationX(getXForChildAtIndex(index)); animationForChild(child) @@ -346,7 +332,7 @@ public class ExpandedAnimationController getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR, /* from */ getExpandedY() /* to */) .start(); - animateBubblesAfterIndexToCorrectX(index); + updateBubblePositions(); } @Override @@ -367,7 +353,7 @@ public class ExpandedAnimationController } // Animate all the other bubbles to their new positions sans this bubble. - animateBubblesAfterIndexToCorrectX(index); + updateBubblePositions(); } @Override @@ -383,21 +369,18 @@ public class ExpandedAnimationController .start(() -> super.setChildVisibility(child, index, visibility) /* after */); } - /** - * Animates the bubbles after the given index to the X position they should be in according to - * {@link #getXForChildAtIndex}. - */ - private void animateBubblesAfterIndexToCorrectX(int start) { - for (int i = start; i < mLayout.getChildCount(); i++) { + private void updateBubblePositions() { + for (int i = 0; i < mLayout.getChildCount(); i++) { final View bubble = mLayout.getChildAt(i); // Don't animate the dragging out bubble, or it'll jump around while being dragged. It // will be snapped to the correct X value after the drag (if it's not dismissed). - if (!bubble.equals(mBubbleDraggingOut)) { - animationForChild(bubble) - .translationX(getXForChildAtIndex(i)) - .start(); + if (bubble.equals(mBubbleDraggingOut)) { + return; } + animationForChild(bubble) + .translationX(getBubbleLeft(i)) + .start(); } } @@ -405,4 +388,34 @@ public class ExpandedAnimationController private float getXForChildAtIndex(int index) { return mBubblePaddingPx + (mBubbleSizePx + mBubblePaddingPx) * index; } + + /** + * @param index Bubble index in row. + * @return Bubble left x from left edge of screen. + */ + public float getBubbleLeft(int index) { + float bubbleLeftFromRowLeft = index * (mBubbleSizePx + mBubblePaddingPx); + return getRowLeft() + bubbleLeftFromRowLeft; + } + + private float getRowLeft() { + if (mLayout == null) { + return 0; + } + int bubbleCount = mLayout.getChildCount(); + if (bubbleCount > mBubblesMaxRendered) { + // Only shown bubbles are relevant for calculating position. + bubbleCount = mBubblesMaxRendered; + } + // Width calculations. + double bubble = bubbleCount * mBubbleSizePx; + float gap = (bubbleCount - 1) * mBubblePaddingPx; + float row = gap + (float) bubble; + + float halfRow = row / 2f; + float centerScreen = mDisplaySize.x / 2; + float rowLeftFromScreenLeft = centerScreen - halfRow; + + return rowLeftFromScreenLeft; + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java index 74b15fb6f215..756cf3e138f6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java @@ -43,10 +43,14 @@ import org.mockito.Spy; @RunWith(AndroidTestingRunner.class) public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestCase { + private int mDisplayWidth = 500; + private int mDisplayHeight = 1000; + @Spy private ExpandedAnimationController mExpandedController = new ExpandedAnimationController( - new Point(500, 1000) /* displaySize */, 0 /* expandedViewPadding */); + new Point(mDisplayWidth, mDisplayHeight) /* displaySize */, + 0 /* expandedViewPadding */); private int mStackOffset; private float mBubblePadding; private float mBubbleSize; @@ -58,11 +62,11 @@ public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestC super.setUp(); addOneMoreThanRenderLimitBubbles(); mLayout.setController(mExpandedController); + Resources res = mLayout.getResources(); mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset); mBubblePadding = res.getDimensionPixelSize(R.dimen.bubble_padding); mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size); - mExpansionPoint = new PointF(100, 100); } @@ -243,7 +247,7 @@ public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestC private void testBubblesInCorrectExpandedPositions() { // Check all the visible bubbles to see if they're in the right place. for (int i = 0; i < Math.min(mLayout.getChildCount(), mMaxRenderedBubbles); i++) { - assertEquals(mBubblePadding + (i * (mBubbleSize + mBubblePadding)), + assertEquals(getBubbleLeft(i), mLayout.getChildAt(i).getTranslationX(), 2f); assertEquals(mExpandedController.getExpandedY(), @@ -254,4 +258,33 @@ public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestC } } } + + /** + * @param index Bubble index in row. + * @return Bubble left x from left edge of screen. + */ + public float getBubbleLeft(int index) { + float bubbleLeftFromRowLeft = index * (mBubbleSize + mBubblePadding); + return getRowLeft() + bubbleLeftFromRowLeft; + } + + private float getRowLeft() { + if (mLayout == null) { + return 0; + } + int bubbleCount = mLayout.getChildCount(); + if (bubbleCount > mMaxRenderedBubbles) { + bubbleCount = mMaxRenderedBubbles; + } + // Width calculations. + double bubble = bubbleCount * mBubbleSize; + float gap = (bubbleCount - 1) * mBubblePadding; + float row = gap + (float) bubble; + + float halfRow = row / 2f; + float centerScreen = mDisplayWidth / 2; + float rowLeftFromScreenLeft = centerScreen - halfRow; + + return rowLeftFromScreenLeft; + } } |