Merge changes I3cfdb715,Ic194afdb into main

* changes:
  Fix initial alpha when unstashing bubble bar
  Set additional bubble translation during stash
This commit is contained in:
Ats Jenk
2024-09-13 22:38:24 +00:00
committed by Android (Google) Code Review
5 changed files with 113 additions and 75 deletions

View File

@@ -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.
*
@@ -997,10 +1010,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);
@@ -1134,6 +1144,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.
*/

View File

@@ -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));

View File

@@ -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);

View File

@@ -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
@@ -301,23 +303,24 @@ class TransientBubbleStashController(
private fun createStashAnimator(isStashed: Boolean, duration: Long): AnimatorSet {
val animatorSet = AnimatorSet()
val alphaDuration = if (isStashed) duration else TASKBAR_STASH_ALPHA_DURATION
val alphaDelay = if (isStashed) TASKBAR_STASH_ALPHA_START_DELAY else 0L
animatorSet.play(
createBackgroundAlphaAnimator(isStashed).apply {
val alphaDuration = if (isStashed) duration else TASKBAR_STASH_ALPHA_DURATION
val alphaDelay = if (isStashed) TASKBAR_STASH_ALPHA_START_DELAY else 0L
this.duration = max(0L, alphaDuration - alphaDelay)
this.startDelay = alphaDelay
this.interpolator = LINEAR
}
)
val iconAlphaTarget = if (isStashed) 0f else 1f
animatorSet.play(
bubbleBarBubbleAlpha.animateToValue(iconAlphaTarget).apply {
this.duration = TASKBAR_STASH_ALPHA_DURATION
this.startDelay = TASKBAR_STASH_ALPHA_START_DELAY
this.interpolator = LINEAR
}
bubbleBarBubbleAlpha
.animateToValue(getBarAlphaStart(isStashed), getBarAlphaEnd(isStashed))
.apply {
this.duration = TASKBAR_STASH_ALPHA_DURATION
this.startDelay = TASKBAR_STASH_ALPHA_START_DELAY
this.interpolator = LINEAR
}
)
animatorSet.play(
@@ -334,6 +337,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
@@ -359,11 +372,15 @@ class TransientBubbleStashController(
)
animatorSet.doOnStart {
if (!isStashed) {
bubbleBarBackgroundAlpha.updateValue(0f)
bubbleBarBubbleAlpha.updateValue(0f)
bubbleBarAlpha.value = 1f
}
// Update the start value for bubble view and background alpha when the entire animation
// begins.
// Alpha animation has a delay, and if we set the initial values at the start of the
// alpha animation, it will cause flickers.
bubbleBarBubbleAlpha.updateValue(getBarAlphaStart(isStashed))
bubbleBarBackgroundAlpha.updateValue(getBarAlphaStart(isStashed))
// We animate alpha for background and bubble views separately. Make sure the container
// is always visible.
bubbleBarAlpha.value = 1f
}
animatorSet.doOnEnd {
animator = null
@@ -373,6 +390,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()
@@ -382,14 +402,29 @@ class TransientBubbleStashController(
}
private fun createBackgroundAlphaAnimator(isStashed: Boolean): AnimatorSet {
val stashHandleAlphaTarget = if (isStashed) 1f else 0f
val barAlphaTarget = if (isStashed) 0f else 1f
return AnimatorSet().apply {
play(bubbleBarBackgroundAlpha.animateToValue(barAlphaTarget))
play(stashHandleViewAlpha?.animateToValue(stashHandleAlphaTarget))
play(
bubbleBarBackgroundAlpha.animateToValue(
getBarAlphaStart(isStashed),
getBarAlphaEnd(isStashed),
)
)
play(stashHandleViewAlpha?.animateToValue(getHandleAlphaEnd(isStashed)))
}
}
private fun getBarAlphaStart(isStashed: Boolean): Float {
return if (isStashed) 1f else 0f
}
private fun getBarAlphaEnd(isStashed: Boolean): Float {
return if (isStashed) 0f else 1f
}
private fun getHandleAlphaEnd(isStashed: Boolean): Float {
return if (isStashed) 1f else 0f
}
private fun createSpringOnStashAnimator(isStashed: Boolean): Animator {
if (!isStashed) {
// Animate the stash translation back to 0

View File

@@ -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,
)
}
@@ -181,9 +186,13 @@ class TransientBubbleStashControllerTest {
assertThat(bubbleBarView.alpha).isEqualTo(0f)
assertThat(bubbleBarView.scaleX).isEqualTo(mTransientBubbleStashController.getStashScaleX())
assertThat(bubbleBarView.scaleY).isEqualTo(mTransientBubbleStashController.getStashScaleY())
assertThat(bubbleBarView.background.alpha).isEqualTo(255)
// 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 +283,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 +294,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 +322,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())
}