Set additional bubble translation during stash
Fixes bubbles stash translation not getting cleared up after stash animation finishes. Bubbles are clipped using an outline animator during the stash animation. They need separate translation applied to keep them within the bounds of the bubble bar that is also shrinking and moving. Set the translation for the bubbles in the stash controller so we can reset the translation after the animation has finished. Bug: 365829293 Flag: com.android.wm.shell.enable_bubble_bar Test: TransientBubbleStashControllerTest Test: have bubbles in bubble bar, trigger a new auto expanding bubble, check translation for bubbles Change-Id: Ic194afdb4d650fcd525355d8bae08dd651d1ea05
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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<BubbleView> 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);
|
||||
|
||||
+18
-3
@@ -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()
|
||||
|
||||
+26
-9
@@ -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<Context>()
|
||||
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())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user