diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java index 1dbf445647..9a1f8765cf 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java @@ -187,6 +187,9 @@ public class BubbleBarView extends FrameLayout { private BubbleView mDismissedByDragBubbleView; private float mAlphaDuringDrag = 1f; + /** Additional translation in the y direction that is applied to each bubble */ + private float mBubbleOffsetY; + private Controller mController; private int mPreviousLayoutDirection = LayoutDirection.UNDEFINED; @@ -334,6 +337,16 @@ public class BubbleBarView extends FrameLayout { mBubbleBarBackground.setAlpha((int) (255 * alpha)); } + /** + * Sets offset of each bubble view in the y direction from the base position in the bar. + */ + public void setBubbleOffsetY(float offsetY) { + mBubbleOffsetY = offsetY; + for (int i = 0; i < getChildCount(); i++) { + getChildAt(i).setTranslationY(getBubbleTranslationY()); + } + } + /** * Sets new icon sizes and newBubbleBarPadding between icons and bubble bar borders. * @@ -994,10 +1007,7 @@ public class BubbleBarView extends FrameLayout { final float expandedWidth = expandedWidth(); final float collapsedWidth = collapsedWidth(); int childCount = getChildCount(); - float viewBottom = mBubbleBarBounds.height() + (isExpanded() ? mPointerSize : 0); - float bubbleBarAnimatedTop = viewBottom - getBubbleBarHeight(); - // When translating X & Y the scale is ignored, so need to deduct it from the translations - final float ty = bubbleBarAnimatedTop + mBubbleBarPadding - getScaleIconShift(); + final float ty = getBubbleTranslationY(); final boolean onLeft = bubbleBarLocation.isOnLeft(isLayoutRtl()); // elevation state is opposite to widthState - when expanded all icons are flat float elevationState = (1 - widthState); @@ -1131,6 +1141,13 @@ public class BubbleBarView extends FrameLayout { return mBubbleBarPadding + translationX - getScaleIconShift(); } + private float getBubbleTranslationY() { + float viewBottom = mBubbleBarBounds.height() + (isExpanded() ? mPointerSize : 0); + float bubbleBarAnimatedTop = viewBottom - getBubbleBarHeight(); + // When translating X & Y the scale is ignored, so need to deduct it from the translations + return mBubbleOffsetY + bubbleBarAnimatedTop + mBubbleBarPadding - getScaleIconShift(); + } + /** * Reorders the views to match the provided list. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java index 570b1b9b4e..ed08de5741 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java @@ -18,11 +18,8 @@ package com.android.launcher3.taskbar.bubbles; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; -import static com.android.launcher3.taskbar.bubbles.BubbleView.STASH_TRANSLATION_Y; - import android.animation.Animator; import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; @@ -97,6 +94,8 @@ public class BubbleBarViewController { this::updateBackgroundScaleY); private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat( this::updateTranslationY); + private final AnimatedFloat mBubbleOffsetY = new AnimatedFloat( + this::updateBubbleOffsetY); // Modified when swipe up is happening on the bubble bar or task bar. private float mBubbleBarSwipeUpTranslationY; @@ -299,6 +298,10 @@ public class BubbleBarViewController { return mBubbleBarTranslationY; } + public AnimatedFloat getBubbleOffsetY() { + return mBubbleOffsetY; + } + public float getBubbleBarCollapsedWidth() { return mBarView.collapsedWidth(); } @@ -576,6 +579,10 @@ public class BubbleBarViewController { mBarView.setBubbleAlpha(alpha); } + private void updateBubbleOffsetY(float transY) { + mBarView.setBubbleOffsetY(transY); + } + private void updateBackgroundAlpha(float alpha) { mBarView.setBackgroundAlpha(alpha); } @@ -874,14 +881,9 @@ public class BubbleBarViewController { mBubbleStashController.getHandleBounds(stashedHandleBounds); int childCount = mBarView.getChildCount(); float newChildWidth = (float) stashedHandleBounds.width() / childCount; - float stashTranslationY = -mBubbleStashController.getBubbleBarTranslationY(); AnimatorSet animatorSet = new AnimatorSet(); for (int i = 0; i < childCount; i++) { BubbleView child = (BubbleView) mBarView.getChildAt(i); - final float startTransY = isStashed ? 0f : stashTranslationY; - final float endTransY = isStashed ? stashTranslationY : 0f; - animatorSet.play( - ObjectAnimator.ofFloat(child, STASH_TRANSLATION_Y, startTransY, endTransY)); animatorSet.play( createRevealAnimForBubble(child, isStashed, stashedHandleBounds, newChildWidth)); diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java index cc6b49a5c7..561df5c2ee 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java @@ -27,7 +27,6 @@ import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.text.TextUtils; import android.util.AttributeSet; -import android.util.FloatProperty; import android.view.LayoutInflater; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ImageView; @@ -50,27 +49,12 @@ public class BubbleView extends ConstraintLayout { public static final int DEFAULT_PATH_SIZE = 100; - public static FloatProperty STASH_TRANSLATION_Y = new FloatProperty<>( - "stashTranslationY") { - @Override - public void setValue(BubbleView bubbleView, float transY) { - bubbleView.setStashTranslationY(transY); - } - - @Override - public Float get(BubbleView bubbleView) { - return bubbleView.mStashTranslationY; - } - }; - private final ImageView mBubbleIcon; private final ImageView mAppIcon; private int mBubbleSize; private float mDragTranslationX; private float mOffsetX; - private float mTranslationY; - private float mStashTranslationY; private DotRenderer mDotRenderer; private DotRenderer.DrawParams mDrawParams; @@ -177,24 +161,6 @@ public class BubbleView extends ConstraintLayout { setTranslationX(mDragTranslationX + mOffsetX); } - /** - * Set translation in y direction during stash and unstash from handle - */ - public void setStashTranslationY(float translationY) { - mStashTranslationY = translationY; - applyTranslationY(); - } - - @Override - public void setTranslationY(float translationY) { - mTranslationY = translationY; - applyTranslationY(); - } - - private void applyTranslationY() { - super.setTranslationY(mTranslationY + mStashTranslationY); - } - @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); 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 5d1e890762..a695a2abad 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt @@ -47,7 +47,7 @@ import kotlin.math.max class TransientBubbleStashController( private val taskbarHotseatDimensionsProvider: TaskbarHotseatDimensionsProvider, - private val context: Context + private val context: Context, ) : BubbleStashController { private lateinit var bubbleBarViewController: BubbleBarViewController @@ -70,6 +70,7 @@ class TransientBubbleStashController( private lateinit var bubbleBarBubbleAlpha: AnimatedFloat private lateinit var bubbleBarBackgroundAlpha: AnimatedFloat private lateinit var bubbleBarTranslationYAnimator: AnimatedFloat + private lateinit var bubbleBarBubbleTranslationY: AnimatedFloat private lateinit var bubbleBarBackgroundScaleX: AnimatedFloat private lateinit var bubbleBarBackgroundScaleY: AnimatedFloat private val handleCenterFromScreenBottom = @@ -143,13 +144,14 @@ class TransientBubbleStashController( taskbarInsetsController: TaskbarInsetsController, bubbleBarViewController: BubbleBarViewController, bubbleStashedHandleViewController: BubbleStashedHandleViewController?, - controllersAfterInitAction: ControllersAfterInitAction + controllersAfterInitAction: ControllersAfterInitAction, ) { this.taskbarInsetsController = taskbarInsetsController this.bubbleBarViewController = bubbleBarViewController this.bubbleStashedHandleViewController = bubbleStashedHandleViewController this.controllersAfterInitAction = controllersAfterInitAction bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY + bubbleBarBubbleTranslationY = bubbleBarViewController.bubbleOffsetY // bubble bar has only alpha property, getting it at index 0 bubbleBarAlpha = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0) bubbleBarBubbleAlpha = bubbleBarViewController.bubbleBarBubbleAlpha @@ -170,7 +172,7 @@ class TransientBubbleStashController( bubbleBarTranslationYAnimator.animateToValue(bubbleBarTranslationY), bubbleBarAlpha.animateToValue(1f), bubbleBarBubbleAlpha.animateToValue(1f), - bubbleBarBackgroundAlpha.animateToValue(1f) + bubbleBarBackgroundAlpha.animateToValue(1f), ) } else { isStashed = true @@ -334,6 +336,16 @@ class TransientBubbleStashController( } ) + // Animate bubble translation to keep reveal animation in the bounds of the bar + val bubbleTyStart = if (isStashed) 0f else -bubbleBarTranslationY + val bubbleTyEnd = if (isStashed) -bubbleBarTranslationY else 0f + animatorSet.play( + bubbleBarBubbleTranslationY.animateToValue(bubbleTyStart, bubbleTyEnd).apply { + this.duration = duration + this.interpolator = EMPHASIZED + } + ) + animatorSet.play( bubbleStashedHandleViewController?.createRevealAnimToIsStashed(isStashed)?.apply { this.duration = duration @@ -373,6 +385,9 @@ class TransientBubbleStashController( // reset bubble view alpha bubbleBarBubbleAlpha.updateValue(1f) bubbleBarBackgroundAlpha.updateValue(1f) + // reset stash translation + translationYDuringStash.updateValue(0f) + bubbleBarBubbleTranslationY.updateValue(0f) bubbleBarViewController.isExpanded = false } taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged() 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 1d13956bd8..19649458bf 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 @@ -32,6 +32,7 @@ import com.android.launcher3.taskbar.TaskbarInsetsController import com.android.launcher3.taskbar.bubbles.BubbleBarView import com.android.launcher3.taskbar.bubbles.BubbleBarViewController import com.android.launcher3.taskbar.bubbles.BubbleStashedHandleViewController +import com.android.launcher3.taskbar.bubbles.BubbleView import com.android.launcher3.util.MultiValueAlpha import com.android.wm.shell.shared.animation.PhysicsAnimator import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils @@ -55,8 +56,8 @@ class TransientBubbleStashControllerTest { companion object { const val TASKBAR_BOTTOM_SPACE = 5 - const val BUBBLE_BAR_WIDTH = 200f - const val BUBBLE_BAR_HEIGHT = 100f + const val BUBBLE_BAR_WIDTH = 200 + const val BUBBLE_BAR_HEIGHT = 100 const val HOTSEAT_TRANSLATION_Y = -45f const val TASK_BAR_TRANSLATION_Y = -TASKBAR_BOTTOM_SPACE const val HANDLE_VIEW_WIDTH = 150 @@ -77,10 +78,12 @@ class TransientBubbleStashControllerTest { private val context = ApplicationProvider.getApplicationContext() private lateinit var bubbleBarView: BubbleBarView private lateinit var stashedHandleView: StashedHandleView + private lateinit var bubbleView: BubbleView private lateinit var barTranslationY: AnimatedFloat private lateinit var barScaleX: AnimatedFloat private lateinit var barScaleY: AnimatedFloat private lateinit var barAlpha: MultiValueAlpha + private lateinit var bubbleOffsetY: AnimatedFloat private lateinit var bubbleAlpha: AnimatedFloat private lateinit var backgroundAlpha: AnimatedFloat private lateinit var stashedHandleAlpha: MultiValueAlpha @@ -105,7 +108,7 @@ class TransientBubbleStashControllerTest { taskbarInsetsController, bubbleBarViewController, bubbleStashedHandleViewController, - ImmediateAction() + ImmediateAction(), ) } @@ -161,11 +164,13 @@ class TransientBubbleStashControllerTest { mTransientBubbleStashController.isStashed = false whenever(bubbleBarViewController.isHiddenForNoBubbles).thenReturn(false) + val bubbleInitialTranslation = bubbleView.translationY + // When stash getInstrumentation().runOnMainSync { mTransientBubbleStashController.updateStashedAndExpandedState( stash = true, - expand = false + expand = false, ) } @@ -184,6 +189,9 @@ class TransientBubbleStashControllerTest { // Handle view is visible assertThat(stashedHandleView.translationY).isEqualTo(0) assertThat(stashedHandleView.alpha).isEqualTo(1) + // Bubble view is reset + assertThat(bubbleView.translationY).isEqualTo(bubbleInitialTranslation) + assertThat(bubbleView.alpha).isEqualTo(1f) } @Test @@ -274,7 +282,7 @@ class TransientBubbleStashControllerTest { val height = mTransientBubbleStashController.getTouchableHeight() // Then bubble bar height is returned - assertThat(height).isEqualTo(BUBBLE_BAR_HEIGHT.toInt()) + assertThat(height).isEqualTo(BUBBLE_BAR_HEIGHT) } private fun advanceTimeBy(advanceMs: Long) { @@ -285,20 +293,26 @@ class TransientBubbleStashControllerTest { private fun setUpBubbleBarView() { getInstrumentation().runOnMainSync { bubbleBarView = BubbleBarView(context) - bubbleBarView.layoutParams = FrameLayout.LayoutParams(0, 0) + bubbleBarView.layoutParams = + FrameLayout.LayoutParams(BUBBLE_BAR_WIDTH, BUBBLE_BAR_HEIGHT) + bubbleView = BubbleView(context) + bubbleBarView.addBubble(bubbleView) + bubbleBarView.layout(0, 0, BUBBLE_BAR_WIDTH, BUBBLE_BAR_HEIGHT) } } private fun setUpStashedHandleView() { getInstrumentation().runOnMainSync { stashedHandleView = StashedHandleView(context) - stashedHandleView.layoutParams = FrameLayout.LayoutParams(0, 0) + stashedHandleView.layoutParams = + FrameLayout.LayoutParams(HANDLE_VIEW_WIDTH, HANDLE_VIEW_HEIGHT) } } private fun setUpBubbleBarController() { barTranslationY = AnimatedFloat(Runnable { bubbleBarView.translationY = barTranslationY.value }) + bubbleOffsetY = AnimatedFloat { value -> bubbleBarView.setBubbleOffsetY(value) } barScaleX = AnimatedFloat { value -> bubbleBarView.scaleX = value } barScaleY = AnimatedFloat { value -> bubbleBarView.scaleY = value } barAlpha = MultiValueAlpha(bubbleBarView, 1 /* num alpha channels */) @@ -307,13 +321,16 @@ class TransientBubbleStashControllerTest { whenever(bubbleBarViewController.hasBubbles()).thenReturn(true) whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(barTranslationY) + whenever(bubbleBarViewController.bubbleOffsetY).thenReturn(bubbleOffsetY) whenever(bubbleBarViewController.bubbleBarBackgroundScaleX).thenReturn(barScaleX) whenever(bubbleBarViewController.bubbleBarBackgroundScaleY).thenReturn(barScaleY) whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(barAlpha) whenever(bubbleBarViewController.bubbleBarBubbleAlpha).thenReturn(bubbleAlpha) whenever(bubbleBarViewController.bubbleBarBackgroundAlpha).thenReturn(backgroundAlpha) - whenever(bubbleBarViewController.bubbleBarCollapsedWidth).thenReturn(BUBBLE_BAR_WIDTH) - whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT) + whenever(bubbleBarViewController.bubbleBarCollapsedWidth) + .thenReturn(BUBBLE_BAR_WIDTH.toFloat()) + whenever(bubbleBarViewController.bubbleBarCollapsedHeight) + .thenReturn(BUBBLE_BAR_HEIGHT.toFloat()) whenever(bubbleBarViewController.createRevealAnimatorForStashChange(any())) .thenReturn(AnimatorSet()) }