Align bubble bar stash anim with taskbar (1/n)
Only scale bubble bar background during stash and unstash animation.
Follows the logic used for taskbar. We scale only the background and
clip the icons separately.
Bug: 345488489
Test: PersistentBubbleStashControllerTest
Test: TransientBubbleStashControllerTest
Test: BubbleBarViewAnimatorTest
Test: stash and unstash bubble bar in app by swiping up from taskbar
Test: expand and collapse bubble bar in app by swiping up on bar
Test: expand and collapse bubble bar on home screen by tapping on it
Flag: com.android.wm.shell.enable_bubble_bar
Change-Id: Ifc7922c444f2179fc49643424815e5e7dde519cc
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
index 25939e1..f08318e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
@@ -71,6 +71,27 @@
}
}
+ /**
+ * Scale of the background in the x direction. Pivot is at the left edge if [anchorLeft] is
+ * `true` and at the right edge if it is `false`
+ */
+ var scaleX: Float = 1f
+ set(value) {
+ if (field != value) {
+ field = value
+ invalidateSelf()
+ }
+ }
+
+ /** Scale of the background in the y direction. Pivot is at the bottom edge. */
+ var scaleY: Float = 1f
+ set(value) {
+ if (field != value) {
+ field = value
+ invalidateSelf()
+ }
+ }
+
init {
val res = context.resources
// configure fill paint
@@ -123,13 +144,17 @@
)
// Create background path
val backgroundPath = Path()
- val topOffset = backgroundHeight - bounds.height().toFloat()
+ val scaledBackgroundHeight = backgroundHeight * scaleY
+ val scaledWidth = width * scaleX
+ val topOffset = scaledBackgroundHeight - bounds.height().toFloat()
val radius = backgroundHeight / 2f
- val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - width)
- val right = bounds.left + (if (anchorLeft) width else bounds.width().toFloat())
- val top = bounds.top - topOffset + arrowVisibleHeight
- val bottom = bounds.top + bounds.height().toFloat()
+ val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - scaledWidth)
+ val right = bounds.left + (if (anchorLeft) scaledWidth else bounds.width().toFloat())
+ // Calculate top with scaled heights for background and arrow to align with stash handle
+ val top = bounds.bottom - scaledBackgroundHeight + getScaledArrowVisibleHeight()
+ val bottom = bounds.bottom.toFloat()
+
backgroundPath.addRoundRect(left, top, right, bottom, radius, radius, Path.Direction.CW)
addArrowPathIfNeeded(backgroundPath, topOffset)
@@ -142,19 +167,20 @@
private fun addArrowPathIfNeeded(sourcePath: Path, topOffset: Float) {
if (!showingArrow || arrowHeightFraction <= 0) return
val arrowPath = Path()
+ val scaledHeight = getScaledArrowHeight()
RoundedArrowDrawable.addDownPointingRoundedTriangleToPath(
arrowWidth,
- arrowHeight,
+ scaledHeight,
arrowTipRadius,
arrowPath
)
// flip it horizontally
val pathTransform = Matrix()
- pathTransform.setRotate(180f, arrowWidth * 0.5f, arrowHeight * 0.5f)
+ pathTransform.setRotate(180f, arrowWidth * 0.5f, scaledHeight * 0.5f)
arrowPath.transform(pathTransform)
// shift to arrow position
val arrowStart = bounds.left + arrowPositionX - (arrowWidth / 2f)
- val arrowTop = (1 - arrowHeightFraction) * arrowVisibleHeight - topOffset
+ val arrowTop = (1 - arrowHeightFraction) * getScaledArrowVisibleHeight() - topOffset
arrowPath.offset(arrowStart, arrowTop)
// union with rectangle
sourcePath.op(arrowPath, Path.Op.UNION)
@@ -183,6 +209,7 @@
fun setBackgroundHeight(newHeight: Float) {
backgroundHeight = newHeight
+ invalidateSelf()
}
/**
@@ -199,6 +226,14 @@
invalidateSelf()
}
+ private fun getScaledArrowHeight(): Float {
+ return arrowHeight * scaleY
+ }
+
+ private fun getScaledArrowVisibleHeight(): Float {
+ return max(0f, getScaledArrowHeight() - (arrowHeight - arrowVisibleHeight))
+ }
+
companion object {
private const val DARK_THEME_STROKE_ALPHA = 51
private const val LIGHT_THEME_STROKE_ALPHA = 41
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index 06301c7..9c6ba8b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -306,6 +306,20 @@
}
/**
+ * Set scale for bubble bar background in x direction
+ */
+ public void setBackgroundScaleX(float scaleX) {
+ mBubbleBarBackground.setScaleX(scaleX);
+ }
+
+ /**
+ * Set scale for bubble bar background in y direction
+ */
+ public void setBackgroundScaleY(float scaleY) {
+ mBubbleBarBackground.setScaleY(scaleY);
+ }
+
+ /**
* Sets new icon sizes and newBubbleBarPadding between icons and bubble bar borders.
*
* @param newIconSize new icon size
@@ -322,7 +336,7 @@
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
- childView.setScaleY(mIconScale);
+ childView.setScaleX(mIconScale);
childView.setScaleY(mIconScale);
FrameLayout.LayoutParams params = (LayoutParams) childView.getLayoutParams();
params.height = (int) mIconSize;
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index d9e3406..d0be5ec 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -82,6 +82,10 @@
private final MultiValueAlpha mBubbleBarAlpha;
private final AnimatedFloat mBubbleBarScaleX = new AnimatedFloat(this::updateScaleX);
private final AnimatedFloat mBubbleBarScaleY = new AnimatedFloat(this::updateScaleY);
+ private final AnimatedFloat mBubbleBarBackgroundScaleX = new AnimatedFloat(
+ this::updateBackgroundScaleX);
+ private final AnimatedFloat mBubbleBarBackgroundScaleY = new AnimatedFloat(
+ this::updateBackgroundScaleY);
private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat(
this::updateTranslationY);
@@ -266,6 +270,14 @@
return mBubbleBarScaleY;
}
+ public AnimatedFloat getBubbleBarBackgroundScaleX() {
+ return mBubbleBarBackgroundScaleX;
+ }
+
+ public AnimatedFloat getBubbleBarBackgroundScaleY() {
+ return mBubbleBarBackgroundScaleY;
+ }
+
public AnimatedFloat getBubbleBarTranslationY() {
return mBubbleBarTranslationY;
}
@@ -535,6 +547,14 @@
mBarView.setScaleY(scale);
}
+ private void updateBackgroundScaleX(float scale) {
+ mBarView.setBackgroundScaleX(scale);
+ }
+
+ private void updateBackgroundScaleY(float scale) {
+ mBarView.setBackgroundScaleY(scale);
+ }
+
//
// Manipulating the specific bubble views in the bar
//
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index 99c50f2..6a955d9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -169,6 +169,8 @@
bubbleBarView.translationY = 0f
bubbleBarView.scaleX = 1f
bubbleBarView.scaleY = BUBBLE_ANIMATION_INITIAL_SCALE_Y
+ bubbleBarView.setBackgroundScaleX(1f)
+ bubbleBarView.setBackgroundScaleY(1f)
bubbleBarView.relativePivotY = 0.5f
// this is the offset between the center of the bubble bar and the center of the stash
@@ -311,6 +313,7 @@
animatingBubble = null
if (!canceled) bubbleStashController.stashBubbleBarImmediate()
bubbleBarView.relativePivotY = 1f
+ bubbleBarView.scaleY = 1f
bubbleStashController.updateTaskbarTouchRegion()
}
animator.start()
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
index 1157305..0700ab7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
@@ -67,8 +67,8 @@
// bubble bar properties
private lateinit var bubbleBarAlpha: MultiPropertyFactory<View>.MultiProperty
private lateinit var bubbleBarTranslationYAnimator: AnimatedFloat
- private lateinit var bubbleBarScaleX: AnimatedFloat
- private lateinit var bubbleBarScaleY: AnimatedFloat
+ private lateinit var bubbleBarBackgroundScaleX: AnimatedFloat
+ private lateinit var bubbleBarBackgroundScaleY: AnimatedFloat
private val handleCenterFromScreenBottom =
context.resources.getDimensionPixelSize(R.dimen.bubblebar_stashed_size) / 2f
@@ -149,8 +149,8 @@
bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY
// bubble bar has only alpha property, getting it at index 0
bubbleBarAlpha = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0)
- bubbleBarScaleX = bubbleBarViewController.bubbleBarScaleX
- bubbleBarScaleY = bubbleBarViewController.bubbleBarScaleY
+ bubbleBarBackgroundScaleX = bubbleBarViewController.bubbleBarBackgroundScaleX
+ bubbleBarBackgroundScaleY = bubbleBarViewController.bubbleBarBackgroundScaleY
stashedHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0
stashHandleViewAlpha = bubbleStashedHandleViewController?.stashedHandleAlpha?.get(0)
}
@@ -160,8 +160,8 @@
if (isBubblesShowingOnHome || isBubblesShowingOnOverview) {
isStashed = false
animatorSet.playTogether(
- bubbleBarScaleX.animateToValue(1f),
- bubbleBarScaleY.animateToValue(1f),
+ bubbleBarBackgroundScaleX.animateToValue(1f),
+ bubbleBarBackgroundScaleY.animateToValue(1f),
bubbleBarTranslationYAnimator.animateToValue(bubbleBarTranslationY),
bubbleBarAlpha.animateToValue(1f)
)
@@ -181,8 +181,8 @@
stashHandleViewAlpha?.value = 0f
this.bubbleBarTranslationYAnimator.updateValue(bubbleBarTranslationY)
bubbleBarAlpha.setValue(1f)
- bubbleBarScaleX.updateValue(1f)
- bubbleBarScaleY.updateValue(1f)
+ bubbleBarBackgroundScaleX.updateValue(1f)
+ bubbleBarBackgroundScaleY.updateValue(1f)
isStashed = false
onIsStashedChanged()
}
@@ -192,8 +192,8 @@
stashHandleViewAlpha?.value = 1f
this.bubbleBarTranslationYAnimator.updateValue(getStashTranslation())
bubbleBarAlpha.setValue(0f)
- bubbleBarScaleX.updateValue(getStashScaleX())
- bubbleBarScaleY.updateValue(getStashScaleY())
+ bubbleBarBackgroundScaleX.updateValue(getStashScaleX())
+ bubbleBarBackgroundScaleY.updateValue(getStashScaleY())
isStashed = true
onIsStashedChanged()
}
@@ -259,7 +259,7 @@
override fun getHandleTranslationY(): Float? = bubbleStashedHandleViewController?.translationY
private fun getStashTranslation(): Float {
- return bubbleBarTranslationY / 2f
+ return (bubbleBarTranslationY - stashedHeight) / 2f
}
@VisibleForTesting
@@ -366,8 +366,8 @@
val scaleXTarget = if (isStashed) getStashScaleX() else 1f
val scaleYTarget = if (isStashed) getStashScaleY() else 1f
return AnimatorSet().apply {
- play(bubbleBarScaleX.animateToValue(scaleXTarget))
- play(bubbleBarScaleY.animateToValue(scaleYTarget))
+ play(bubbleBarBackgroundScaleX.animateToValue(scaleXTarget))
+ play(bubbleBarBackgroundScaleY.animateToValue(scaleYTarget))
}
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
index 262d8da..a745b66 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
@@ -60,7 +60,7 @@
const val TASK_BAR_TRANSLATION_Y = -TASKBAR_BOTTOM_SPACE
const val HANDLE_VIEW_WIDTH = 150
const val HANDLE_VIEW_HEIGHT = 4
- const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -2.5f
+ const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -4.5f
}
@get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this)
@@ -302,8 +302,8 @@
whenever(bubbleBarViewController.hasBubbles()).thenReturn(true)
whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(barTranslationY)
- whenever(bubbleBarViewController.bubbleBarScaleX).thenReturn(barScaleX)
- whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(barScaleY)
+ whenever(bubbleBarViewController.bubbleBarBackgroundScaleX).thenReturn(barScaleX)
+ whenever(bubbleBarViewController.bubbleBarBackgroundScaleY).thenReturn(barScaleY)
whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(barAlpha)
whenever(bubbleBarViewController.bubbleBarCollapsedWidth).thenReturn(BUBBLE_BAR_WIDTH)
whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT)