Merge "Drag and drop from the search view on the overview screen." into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
c12d67c4e0
@@ -20,6 +20,7 @@ import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.dynamicanimation.animation.SpringForce
|
||||
import com.android.app.animation.Interpolators
|
||||
@@ -30,11 +31,10 @@ import com.android.wm.shell.shared.bubbles.BubbleBarLocation
|
||||
|
||||
/** Animator helper that creates bars animators. */
|
||||
object BarsLocationAnimatorHelper {
|
||||
|
||||
private const val FADE_OUT_ANIM_ALPHA_DURATION_MS: Long = 50L
|
||||
private const val FADE_OUT_ANIM_ALPHA_DELAY_MS: Long = 50L
|
||||
private const val FADE_OUT_ANIM_POSITION_DURATION_MS: Long = 100L
|
||||
private const val FADE_IN_ANIM_ALPHA_DURATION_MS: Long = 100L
|
||||
const val FADE_OUT_ANIM_ALPHA_DURATION_MS: Long = 50L
|
||||
const val FADE_OUT_ANIM_ALPHA_DELAY_MS: Long = 50L
|
||||
const val FADE_OUT_ANIM_POSITION_DURATION_MS: Long = 100L
|
||||
const val FADE_IN_ANIM_ALPHA_DURATION_MS: Long = 100L
|
||||
|
||||
// Use STIFFNESS_MEDIUMLOW which is not defined in the API constants
|
||||
private const val FADE_IN_ANIM_POSITION_SPRING_STIFFNESS: Float = 400f
|
||||
@@ -45,13 +45,13 @@ object BarsLocationAnimatorHelper {
|
||||
// During fade in animation we shift the bubble bar 1/60th of the screen width
|
||||
private const val FADE_IN_ANIM_POSITION_SHIFT: Float = 1 / 60f
|
||||
|
||||
private val View.screenWidth: Int
|
||||
private val Context.screenWidth: Int
|
||||
get() = resources.displayMetrics.widthPixels
|
||||
|
||||
private val View.outShift: Float
|
||||
val Context.outShift: Float
|
||||
get() = screenWidth * FADE_OUT_ANIM_POSITION_SHIFT
|
||||
|
||||
private val View.inShiftX: Float
|
||||
val Context.inShiftX: Float
|
||||
get() = screenWidth * FADE_IN_ANIM_POSITION_SHIFT
|
||||
|
||||
/**
|
||||
@@ -108,7 +108,7 @@ object BarsLocationAnimatorHelper {
|
||||
targetViewAlphaAnim: ObjectAnimator,
|
||||
bubbleBarView: View,
|
||||
): Animator {
|
||||
val shift: Float = bubbleBarView.outShift
|
||||
val shift: Float = bubbleBarView.context.outShift
|
||||
|
||||
val onLeft = newLocation.isOnLeft(bubbleBarView.isLayoutRtl)
|
||||
val startTx: Float
|
||||
@@ -132,15 +132,19 @@ object BarsLocationAnimatorHelper {
|
||||
return createLocationInAnimator(startTx, finalTx, targetViewAlphaAnim, bubbleBarView)
|
||||
}
|
||||
|
||||
/** Creates an animator for the bubble bar view out part. */
|
||||
/**
|
||||
* Creates an animator for the bubble bar view out part.
|
||||
*
|
||||
* @param targetLocation the location bubble bar should animate to.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getBubbleBarLocationOutAnimator(
|
||||
bubbleBarView: View,
|
||||
bubbleBarLocation: BubbleBarLocation,
|
||||
targetLocation: BubbleBarLocation,
|
||||
targetViewAlphaAnim: ObjectAnimator,
|
||||
): Animator {
|
||||
val onLeft = bubbleBarLocation.isOnLeft(bubbleBarView.isLayoutRtl)
|
||||
val shift = bubbleBarView.outShift
|
||||
val onLeft = targetLocation.isOnLeft(bubbleBarView.isLayoutRtl)
|
||||
val shift = bubbleBarView.context.outShift
|
||||
val finalTx = bubbleBarView.translationX + (if (onLeft) -shift else shift)
|
||||
return this.createLocationOutAnimator(finalTx, targetViewAlphaAnim, bubbleBarView)
|
||||
}
|
||||
@@ -152,7 +156,7 @@ object BarsLocationAnimatorHelper {
|
||||
navButtonsView: View,
|
||||
navBarTargetTranslationX: Float,
|
||||
): Animator {
|
||||
val outShift: Float = navButtonsView.outShift
|
||||
val outShift: Float = navButtonsView.context.outShift
|
||||
val isNavBarOnRight: Boolean = location.isOnLeft(navButtonsView.isLayoutRtl)
|
||||
val finalOutTx =
|
||||
navButtonsView.translationX + (if (isNavBarOnRight) outShift else -outShift)
|
||||
@@ -162,7 +166,7 @@ object BarsLocationAnimatorHelper {
|
||||
ObjectAnimator.ofFloat(navButtonsView, LauncherAnimUtils.VIEW_ALPHA, 0f),
|
||||
navButtonsView,
|
||||
)
|
||||
val inShift: Float = navButtonsView.inShiftX
|
||||
val inShift: Float = navButtonsView.context.inShiftX
|
||||
val inStartX = navBarTargetTranslationX + (if (isNavBarOnRight) -inShift else inShift)
|
||||
val fadeIn: Animator =
|
||||
createLocationInAnimator(
|
||||
|
||||
@@ -510,6 +510,8 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
|
||||
} else {
|
||||
// This will take care of calling maybeOnDragEnd() after the animation
|
||||
animateGlobalDragViewToOriginalPosition(btv, dragEvent);
|
||||
//TODO(b/399678274): hide drop target in shell
|
||||
notifyBubbleBarItemDragCanceled();
|
||||
}
|
||||
mActivity.getDragLayer().setOnDragListener(null);
|
||||
|
||||
@@ -536,10 +538,10 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
|
||||
mControllers.taskbarAutohideSuspendController.updateFlag(
|
||||
TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING, false);
|
||||
mActivity.onDragEnd();
|
||||
// If an item is dropped on the bubble bar, the bubble bar handles the drop,
|
||||
// so it should not collapse along with the taskbar.
|
||||
boolean droppedOnBubbleBar = notifyBubbleBarItemDropped();
|
||||
if (mReturnAnimator == null) {
|
||||
// If an item is dropped on the bubble bar, the bubble bar handles the drop,
|
||||
// so it should not collapse along with the taskbar.
|
||||
boolean droppedOnBubbleBar = notifyBubbleBarItemDropped();
|
||||
// Upon successful drag, immediately stash taskbar.
|
||||
// Note, this must be done last to ensure no AutohideSuspendFlags are active, as
|
||||
// that will prevent us from stashing until the timeout.
|
||||
@@ -563,12 +565,17 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
|
||||
BubbleBarViewController bubbleBarViewController = bc.bubbleBarViewController;
|
||||
boolean showingDropTarget = bubbleBarViewController.isShowingDropTarget();
|
||||
if (showingDropTarget) {
|
||||
bubbleBarViewController.onItemDroppedInBubbleBarDragZone();
|
||||
bubbleBarViewController.onItemDragCompleted();
|
||||
}
|
||||
return showingDropTarget;
|
||||
}).orElse(false);
|
||||
}
|
||||
|
||||
private void notifyBubbleBarItemDragCanceled() {
|
||||
mControllers.bubbleControllers.ifPresent(bc ->
|
||||
bc.bubbleBarViewController.onItemDraggedOutsideBubbleBarDropZone());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endDrag() {
|
||||
if (mDisallowGlobalDrag && !mIsDropHandledByDropTarget) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.launcher3.taskbar.bubbles;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.NonNull;
|
||||
@@ -560,30 +561,52 @@ public class BubbleBarView extends FrameLayout {
|
||||
// First animator hides the bar.
|
||||
// After it completes, bubble positions in the bar and arrow position is updated.
|
||||
// Second animator is started to show the bar.
|
||||
ObjectAnimator alphaOutAnim = ObjectAnimator.ofFloat(
|
||||
this, getLocationAnimAlphaProperty(), 0f);
|
||||
mBubbleBarLocationAnimator = BarsLocationAnimatorHelper.getBubbleBarLocationOutAnimator(
|
||||
this,
|
||||
bubbleBarLocation,
|
||||
alphaOutAnim);
|
||||
mBubbleBarLocationAnimator = animateToBubbleBarLocationOut(bubbleBarLocation);
|
||||
mBubbleBarLocationAnimator.addListener(AnimatorListeners.forEndCallback(() -> {
|
||||
updateBubblesLayoutProperties(bubbleBarLocation);
|
||||
mBubbleBarBackground.setAnchorLeft(bubbleBarLocation.isOnLeft(isLayoutRtl()));
|
||||
ObjectAnimator alphaInAnim = ObjectAnimator.ofFloat(BubbleBarView.this,
|
||||
getLocationAnimAlphaProperty(), 1f);
|
||||
|
||||
// Animate it in
|
||||
mBubbleBarLocationAnimator = BarsLocationAnimatorHelper.getBubbleBarLocationInAnimator(
|
||||
bubbleBarLocation,
|
||||
mBubbleBarLocation,
|
||||
getDistanceFromOtherSide(),
|
||||
alphaInAnim,
|
||||
BubbleBarView.this);
|
||||
mBubbleBarLocationAnimator = animateToBubbleBarLocationIn(mBubbleBarLocation,
|
||||
bubbleBarLocation);
|
||||
mBubbleBarLocationAnimator.start();
|
||||
}));
|
||||
mBubbleBarLocationAnimator.start();
|
||||
}
|
||||
|
||||
/** Creates animator for animating bubble bar in. */
|
||||
public Animator animateToBubbleBarLocationIn(BubbleBarLocation fromLocation,
|
||||
BubbleBarLocation toLocation) {
|
||||
updateBubblesLayoutProperties(toLocation);
|
||||
mBubbleBarBackground.setAnchorLeft(toLocation.isOnLeft(isLayoutRtl()));
|
||||
ObjectAnimator alphaInAnim = ObjectAnimator.ofFloat(BubbleBarView.this,
|
||||
getLocationAnimAlphaProperty(), 1f);
|
||||
return BarsLocationAnimatorHelper.getBubbleBarLocationInAnimator(toLocation, fromLocation,
|
||||
getDistanceFromOtherSide(), alphaInAnim, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates animator for animating bubble bar out.
|
||||
*
|
||||
* @param targetLocation the location bubble br should animate to.
|
||||
*/
|
||||
public Animator animateToBubbleBarLocationOut(BubbleBarLocation targetLocation) {
|
||||
ObjectAnimator alphaOutAnim = ObjectAnimator.ofFloat(
|
||||
this, getLocationAnimAlphaProperty(), 0f);
|
||||
Animator outAnimation = BarsLocationAnimatorHelper.getBubbleBarLocationOutAnimator(
|
||||
this,
|
||||
targetLocation,
|
||||
alphaOutAnim);
|
||||
outAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) {
|
||||
// need to restore the original bar view state in case icon is dropped to the bubble
|
||||
// bar original location
|
||||
updateBubblesLayoutProperties(targetLocation);
|
||||
mBubbleBarBackground.setAnchorLeft(targetLocation.isOnLeft(isLayoutRtl()));
|
||||
setTranslationX(0f);
|
||||
}
|
||||
});
|
||||
return outAnimation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property that can be used to animate the alpha value for the bar.
|
||||
* When a bubble is being dragged, uses {@link #BUBBLE_DRAG_ALPHA}.
|
||||
|
||||
@@ -194,9 +194,11 @@ public class BubbleBarViewController {
|
||||
private boolean mHiddenForStashed;
|
||||
private boolean mShouldShowEducation;
|
||||
public boolean mOverflowAdded;
|
||||
private boolean mIsLocationUpdatedForDropTarget = false;
|
||||
private boolean mWasStashedBeforeEnteringBubbleDragZone = false;
|
||||
|
||||
/** This field is used solely to track the bubble bar location prior to the start of the drag */
|
||||
private @Nullable BubbleBarLocation mBubbleBarDragLocation;
|
||||
|
||||
private BubbleBarViewAnimator mBubbleBarViewAnimator;
|
||||
private final FrameLayout mBubbleBarContainer;
|
||||
private BubbleBarFlyoutController mBubbleBarFlyoutController;
|
||||
@@ -364,7 +366,7 @@ public class BubbleBarViewController {
|
||||
@Override
|
||||
public boolean isOnLeft() {
|
||||
boolean shouldRevertLocation =
|
||||
mBarView.isShowingDropTarget() && mIsLocationUpdatedForDropTarget;
|
||||
mBarView.isShowingDropTarget() && isLocationUpdatedForDropTarget();
|
||||
boolean isOnLeft = mBarView.getBubbleBarLocation().isOnLeft(mBarView.isLayoutRtl());
|
||||
return shouldRevertLocation != isOnLeft;
|
||||
}
|
||||
@@ -616,6 +618,17 @@ public class BubbleBarViewController {
|
||||
mBarView.animateToBubbleBarLocation(bubbleBarLocation);
|
||||
}
|
||||
|
||||
/** Return animator for animating bubble bar in. */
|
||||
public Animator animateBubbleBarLocationIn(BubbleBarLocation fromLocation,
|
||||
BubbleBarLocation toLocation) {
|
||||
return mBarView.animateToBubbleBarLocationIn(fromLocation, toLocation);
|
||||
}
|
||||
|
||||
/** Return animator for animating bubble bar out. */
|
||||
public Animator animateBubbleBarLocationOut(BubbleBarLocation toLocation) {
|
||||
return mBarView.animateToBubbleBarLocationOut(toLocation);
|
||||
}
|
||||
|
||||
/** Returns whether the Bubble Bar is currently displaying a drop target. */
|
||||
public boolean isShowingDropTarget() {
|
||||
return mBarView.isShowingDropTarget();
|
||||
@@ -628,25 +641,18 @@ public class BubbleBarViewController {
|
||||
* updated.
|
||||
*/
|
||||
public void onDragItemOverBubbleBarDragZone(@NonNull BubbleBarLocation bubbleBarLocation) {
|
||||
Log.w("BBAnimation", "onDragItemOverBubbleBarDragZone()");
|
||||
mBubbleBarDragLocation = bubbleBarLocation;
|
||||
mBarView.showDropTarget(/* isDropTarget = */ true);
|
||||
boolean isRtl = mBarView.isLayoutRtl();
|
||||
mIsLocationUpdatedForDropTarget = getBubbleBarLocation().isOnLeft(isRtl)
|
||||
!= bubbleBarLocation.isOnLeft(isRtl);
|
||||
mWasStashedBeforeEnteringBubbleDragZone = hasBubbles()
|
||||
&& mBubbleStashController.isStashed();
|
||||
if (mWasStashedBeforeEnteringBubbleDragZone) {
|
||||
if (mIsLocationUpdatedForDropTarget) {
|
||||
// bubble bar is stashed an location updated
|
||||
//TODO(b/399678274) add animation
|
||||
mBubbleStashController.showBubbleBarImmediate();
|
||||
animateBubbleBarLocation(bubbleBarLocation);
|
||||
} else {
|
||||
// bubble bar is stashed and location the same - just un-stash
|
||||
mBubbleStashController.showBubbleBar(/* expandBubbles = */ false);
|
||||
}
|
||||
// bubble bar is stashed - un-stash at drag location
|
||||
mBubbleStashController.showBubbleBarAtLocation(
|
||||
/* fromLocation = */ getBubbleBarLocation(),
|
||||
/* toLocation = */ mBubbleBarDragLocation
|
||||
);
|
||||
} else if (hasBubbles()) {
|
||||
if (mIsLocationUpdatedForDropTarget) {
|
||||
if (isLocationUpdatedForDropTarget()) {
|
||||
// bubble bar has bubbles and location is changed - animate bar to the opposite side
|
||||
animateBubbleBarLocation(bubbleBarLocation);
|
||||
}
|
||||
@@ -661,7 +667,12 @@ public class BubbleBarViewController {
|
||||
* {@link #onDragItemOverBubbleBarDragZone}}.
|
||||
*/
|
||||
public boolean isLocationUpdatedForDropTarget() {
|
||||
return mIsLocationUpdatedForDropTarget;
|
||||
if (mBubbleBarDragLocation == null) {
|
||||
return false;
|
||||
}
|
||||
boolean isRtl = mBarView.isLayoutRtl();
|
||||
return getBubbleBarLocation().isOnLeft(isRtl)
|
||||
!= mBubbleBarDragLocation.isOnLeft(isRtl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -671,39 +682,34 @@ public class BubbleBarViewController {
|
||||
* mode and reset the value returned from {@link #isLocationUpdatedForDropTarget()} to false.
|
||||
*/
|
||||
public void onItemDraggedOutsideBubbleBarDropZone() {
|
||||
Log.w("BBAnimation", "onItemDraggedOutsideBubbleBarDropZone()");
|
||||
mBarView.showDropTarget(/* isDropTarget = */ false);
|
||||
if (mWasStashedBeforeEnteringBubbleDragZone) {
|
||||
if (mIsLocationUpdatedForDropTarget) {
|
||||
// bubble bar was stashed and location updated
|
||||
//TODO(b/399678274) add animation
|
||||
animateBubbleBarLocation(getBubbleBarLocation());
|
||||
mBubbleStashController.stashBubbleBarImmediate();
|
||||
} else {
|
||||
// bubble bar was stashed and location the same - just stash it back
|
||||
mBubbleStashController.stashBubbleBar();
|
||||
}
|
||||
if (!isShowingDropTarget()) {
|
||||
return;
|
||||
}
|
||||
if (mWasStashedBeforeEnteringBubbleDragZone && mBubbleBarDragLocation != null) {
|
||||
// bubble bar was stashed - stash at original location
|
||||
mBubbleStashController.stashBubbleBarToLocation(
|
||||
/* fromLocation = */ mBubbleBarDragLocation,
|
||||
/* toLocation = */ getBubbleBarLocation()
|
||||
);
|
||||
} else if (hasBubbles()) {
|
||||
if (mIsLocationUpdatedForDropTarget) {
|
||||
// bubble bar has bubbles and location was changed - return to the original location
|
||||
if (isLocationUpdatedForDropTarget()) {
|
||||
// bubble bar has bubbles and location was changed - return to the original
|
||||
// location
|
||||
animateBubbleBarLocation(getBubbleBarLocation());
|
||||
}
|
||||
}
|
||||
mBubbleBarPinController.hideDropTarget();
|
||||
mIsLocationUpdatedForDropTarget = false;
|
||||
mWasStashedBeforeEnteringBubbleDragZone = false;
|
||||
onItemDragCompleted();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the controller that the drag has completed over the Bubble Bar drop zone.
|
||||
* The controller will hide the drop target if there are no bubbles and exit drop target mode.
|
||||
*/
|
||||
public void onItemDroppedInBubbleBarDragZone() {
|
||||
Log.w("BBAnimation", "onItemDroppedInBubbleBarDragZone()");
|
||||
public void onItemDragCompleted() {
|
||||
mBarView.showDropTarget(/* isDropTarget = */ false);
|
||||
mBubbleBarPinController.hideDropTarget();
|
||||
mIsLocationUpdatedForDropTarget = false;
|
||||
mWasStashedBeforeEnteringBubbleDragZone = false;
|
||||
mBubbleBarDragLocation = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -842,6 +848,7 @@ public class BubbleBarViewController {
|
||||
boolean hiddenForStashedAndNotAnimating =
|
||||
mHiddenForStashed && !mBubbleBarViewAnimator.isAnimating();
|
||||
if (mHiddenForSysui || mHiddenForNoBubbles || hiddenForStashedAndNotAnimating) {
|
||||
//TODO(b/404870188) this visibility change cause search view drag misbehavior
|
||||
mBarView.setVisibility(INVISIBLE);
|
||||
} else {
|
||||
mBarView.setVisibility(VISIBLE);
|
||||
|
||||
+5
@@ -272,6 +272,11 @@ public class BubbleStashedHandleViewController {
|
||||
updateTranslationY();
|
||||
}
|
||||
|
||||
/** Sets translation X for stash handle. */
|
||||
public void setTranslationX(float translationX) {
|
||||
mStashedHandleView.setTranslationX(translationX);
|
||||
}
|
||||
|
||||
private void updateTranslationY() {
|
||||
mStashedHandleView.setTranslationY(mTranslationForSwipeY + mTranslationForStashY);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,12 @@ interface BubbleStashController {
|
||||
*/
|
||||
fun stashBubbleBar()
|
||||
|
||||
/**
|
||||
* Animates the bubble bar to the handle at provided location. Does not update bubble bar
|
||||
* location.
|
||||
*/
|
||||
fun stashBubbleBarToLocation(fromLocation: BubbleBarLocation, toLocation: BubbleBarLocation) {}
|
||||
|
||||
/** Shows the bubble bar, and expands bubbles depending on [expandBubbles]. */
|
||||
fun showBubbleBar(expandBubbles: Boolean) {
|
||||
showBubbleBar(expandBubbles = expandBubbles, bubbleBarGesture = false)
|
||||
@@ -144,6 +150,9 @@ interface BubbleStashController {
|
||||
*/
|
||||
fun showBubbleBar(expandBubbles: Boolean, bubbleBarGesture: Boolean)
|
||||
|
||||
/** Animates the bubble bar at the provided location. Does not update bubble bar location. */
|
||||
fun showBubbleBarAtLocation(fromLocation: BubbleBarLocation, toLocation: BubbleBarLocation) {}
|
||||
|
||||
// TODO(b/354218264): Move to BubbleBarViewAnimator
|
||||
/**
|
||||
* The difference on the Y axis between the center of the handle and the center of the bubble
|
||||
|
||||
+127
-5
@@ -18,6 +18,7 @@ package com.android.launcher3.taskbar.bubbles.stashing
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.view.MotionEvent
|
||||
@@ -31,6 +32,12 @@ import com.android.app.animation.Interpolators.LINEAR
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.anim.AnimatedFloat
|
||||
import com.android.launcher3.anim.SpringAnimationBuilder
|
||||
import com.android.launcher3.taskbar.BarsLocationAnimatorHelper.FADE_IN_ANIM_ALPHA_DURATION_MS
|
||||
import com.android.launcher3.taskbar.BarsLocationAnimatorHelper.FADE_OUT_ANIM_ALPHA_DELAY_MS
|
||||
import com.android.launcher3.taskbar.BarsLocationAnimatorHelper.FADE_OUT_ANIM_ALPHA_DURATION_MS
|
||||
import com.android.launcher3.taskbar.BarsLocationAnimatorHelper.FADE_OUT_ANIM_POSITION_DURATION_MS
|
||||
import com.android.launcher3.taskbar.BarsLocationAnimatorHelper.inShiftX
|
||||
import com.android.launcher3.taskbar.BarsLocationAnimatorHelper.outShift
|
||||
import com.android.launcher3.taskbar.TaskbarInsetsController
|
||||
import com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH_ALPHA_START_DELAY
|
||||
import com.android.launcher3.taskbar.TaskbarStashController.TRANSIENT_TASKBAR_STASH_ALPHA_DURATION
|
||||
@@ -44,6 +51,7 @@ import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Task
|
||||
import com.android.launcher3.util.MultiPropertyFactory
|
||||
import com.android.wm.shell.shared.animation.PhysicsAnimator
|
||||
import com.android.wm.shell.shared.bubbles.BubbleBarLocation
|
||||
import com.android.wm.shell.shared.bubbles.ContextUtils.isRtl
|
||||
import kotlin.math.max
|
||||
|
||||
class TransientBubbleStashController(
|
||||
@@ -187,6 +195,11 @@ class TransientBubbleStashController(
|
||||
}
|
||||
|
||||
override fun showBubbleBarImmediate(bubbleBarTranslationY: Float) {
|
||||
showBubbleBarImmediateVisually(bubbleBarTranslationY)
|
||||
onIsStashedChanged()
|
||||
}
|
||||
|
||||
private fun showBubbleBarImmediateVisually(bubbleBarTranslationY: Float) {
|
||||
bubbleStashedHandleViewController?.setTranslationYForSwipe(0f)
|
||||
stashHandleViewAlpha?.value = 0f
|
||||
this.bubbleBarTranslationYAnimator.updateValue(bubbleBarTranslationY)
|
||||
@@ -197,10 +210,14 @@ class TransientBubbleStashController(
|
||||
bubbleBarBackgroundScaleY.updateValue(1f)
|
||||
isStashed = false
|
||||
bubbleBarViewController.setHiddenForStashed(false)
|
||||
onIsStashedChanged()
|
||||
}
|
||||
|
||||
override fun stashBubbleBarImmediate() {
|
||||
stashBubbleBarImmediateVisually()
|
||||
onIsStashedChanged()
|
||||
}
|
||||
|
||||
private fun stashBubbleBarImmediateVisually() {
|
||||
bubbleStashedHandleViewController?.setTranslationYForSwipe(0f)
|
||||
stashHandleViewAlpha?.value = 1f
|
||||
this.bubbleBarTranslationYAnimator.updateValue(getStashTranslation())
|
||||
@@ -212,7 +229,6 @@ class TransientBubbleStashController(
|
||||
bubbleBarBackgroundScaleY.updateValue(getStashScaleY())
|
||||
isStashed = true
|
||||
bubbleBarViewController.setHiddenForStashed(true)
|
||||
onIsStashedChanged()
|
||||
}
|
||||
|
||||
override fun getTouchableHeight(): Int =
|
||||
@@ -247,6 +263,29 @@ class TransientBubbleStashController(
|
||||
updateStashedAndExpandedState(stash = true, expand = false)
|
||||
}
|
||||
|
||||
override fun stashBubbleBarToLocation(
|
||||
fromLocation: BubbleBarLocation,
|
||||
toLocation: BubbleBarLocation,
|
||||
) {
|
||||
if (fromLocation.isSameSideWith(toLocation)) {
|
||||
updateStashedAndExpandedState(
|
||||
stash = true,
|
||||
expand = false,
|
||||
updateTouchRegionOnEnd = false,
|
||||
)
|
||||
return
|
||||
}
|
||||
cancelAnimation()
|
||||
animator =
|
||||
AnimatorSet().apply {
|
||||
playSequentially(
|
||||
bubbleBarViewController.animateBubbleBarLocationOut(toLocation),
|
||||
createHandleInAnimator(location = toLocation),
|
||||
)
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
override fun showBubbleBar(expandBubbles: Boolean, bubbleBarGesture: Boolean) {
|
||||
updateStashedAndExpandedState(
|
||||
stash = false,
|
||||
@@ -255,6 +294,33 @@ class TransientBubbleStashController(
|
||||
)
|
||||
}
|
||||
|
||||
override fun showBubbleBarAtLocation(
|
||||
fromLocation: BubbleBarLocation,
|
||||
toLocation: BubbleBarLocation,
|
||||
) {
|
||||
if (fromLocation.isSameSideWith(toLocation)) {
|
||||
updateStashedAndExpandedState(
|
||||
stash = false,
|
||||
expand = false,
|
||||
updateTouchRegionOnEnd = false,
|
||||
)
|
||||
return
|
||||
}
|
||||
cancelAnimation()
|
||||
val bubbleBarInAnimation =
|
||||
bubbleBarViewController.animateBubbleBarLocationIn(fromLocation, toLocation).apply {
|
||||
doOnStart { showBubbleBarImmediateVisually(bubbleBarTranslationY) }
|
||||
}
|
||||
animator =
|
||||
AnimatorSet().apply {
|
||||
playSequentially(
|
||||
createHandleOutAnimator(location = toLocation),
|
||||
bubbleBarInAnimation,
|
||||
)
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDiffBetweenHandleAndBarCenters(): Float {
|
||||
// the difference between the centers of the handle and the bubble bar is the difference
|
||||
// between their distance from the bottom of the screen.
|
||||
@@ -392,7 +458,7 @@ class TransientBubbleStashController(
|
||||
bubbleBarAlpha.value = 1f
|
||||
}
|
||||
animatorSet.doOnEnd {
|
||||
animator = null
|
||||
cancelAnimation()
|
||||
controllersAfterInitAction.runAfterInit {
|
||||
if (isStashed) {
|
||||
bubbleBarAlpha.value = 0f
|
||||
@@ -486,6 +552,7 @@ class TransientBubbleStashController(
|
||||
stash: Boolean,
|
||||
expand: Boolean,
|
||||
bubbleBarGesture: Boolean = false,
|
||||
updateTouchRegionOnEnd: Boolean = true,
|
||||
) {
|
||||
if (bubbleBarViewController.isHiddenForNoBubbles) {
|
||||
// If there are no bubbles the bar and handle are invisible, nothing to do here.
|
||||
@@ -498,11 +565,13 @@ class TransientBubbleStashController(
|
||||
// notify the view controller that the stash state is about to change so that it can
|
||||
// cancel an ongoing animation if there is one.
|
||||
bubbleBarViewController.onStashStateChanging()
|
||||
animator?.cancel()
|
||||
cancelAnimation()
|
||||
animator =
|
||||
createStashAnimator(isStashed, BAR_STASH_DURATION).apply {
|
||||
updateBarVisibility(isStashed)
|
||||
updateTouchRegionOnAnimationEnd()
|
||||
if (updateTouchRegionOnEnd) {
|
||||
updateTouchRegionOnAnimationEnd()
|
||||
}
|
||||
start()
|
||||
}
|
||||
}
|
||||
@@ -512,6 +581,11 @@ class TransientBubbleStashController(
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelAnimation() {
|
||||
animator?.cancel()
|
||||
animator = null
|
||||
}
|
||||
|
||||
override fun getHandleViewAlpha(): MultiPropertyFactory<View>.MultiProperty? =
|
||||
// only return handle alpha if the bubble bar is stashed and has bubbles
|
||||
if (isStashed && bubbleBarViewController.hasBubbles()) {
|
||||
@@ -534,6 +608,49 @@ class TransientBubbleStashController(
|
||||
return this
|
||||
}
|
||||
|
||||
// TODO(b/399678274) add tests
|
||||
private fun createHandleInAnimator(location: BubbleBarLocation): Animator? {
|
||||
val stashHandleViewController = bubbleStashedHandleViewController ?: return null
|
||||
val handleAlpha = stashHandleViewController.stashedHandleAlpha.get(0)
|
||||
val shift = context.inShiftX
|
||||
val startX = if (location.isOnLeft(context.isRtl)) shift else -shift
|
||||
val handleTranslationX =
|
||||
ValueAnimator.ofFloat(startX, 0f).apply {
|
||||
addUpdateListener { v ->
|
||||
stashHandleViewController.setTranslationX(v.animatedValue as Float)
|
||||
}
|
||||
duration = FADE_IN_ANIM_ALPHA_DURATION_MS
|
||||
}
|
||||
val handleAlphaAnimation =
|
||||
handleAlpha.animateToValue(1f).apply { duration = FADE_IN_ANIM_ALPHA_DURATION_MS }
|
||||
return AnimatorSet().apply {
|
||||
playTogether(handleTranslationX, handleAlphaAnimation)
|
||||
doOnStart { stashBubbleBarImmediateVisually() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun createHandleOutAnimator(location: BubbleBarLocation): Animator? {
|
||||
val stashHandleViewController = bubbleStashedHandleViewController ?: return null
|
||||
val handleAlpha = stashHandleViewController.stashedHandleAlpha.get(0)
|
||||
val shift = context.outShift
|
||||
val endX = if (location.isOnLeft(context.isRtl)) -shift else shift
|
||||
val handleTranslationX =
|
||||
ValueAnimator.ofFloat(0f, endX).apply {
|
||||
addUpdateListener { v ->
|
||||
stashHandleViewController.setTranslationX(v.animatedValue as Float)
|
||||
}
|
||||
duration = FADE_OUT_ANIM_POSITION_DURATION_MS
|
||||
// in case item dropped to the opposite side - need to clear translation
|
||||
doOnEnd { stashHandleViewController.setTranslationX(0f) }
|
||||
}
|
||||
val handleAlphaAnimation =
|
||||
handleAlpha.animateToValue(0f).apply {
|
||||
duration = FADE_OUT_ANIM_ALPHA_DURATION_MS
|
||||
startDelay = FADE_OUT_ANIM_ALPHA_DELAY_MS
|
||||
}
|
||||
return AnimatorSet().apply { playTogether(handleTranslationX, handleAlphaAnimation) }
|
||||
}
|
||||
|
||||
private fun Animator.setBubbleBarPivotDuringAnim(pivotX: Float, pivotY: Float): Animator {
|
||||
var initialPivotX = Float.NaN
|
||||
var initialPivotY = Float.NaN
|
||||
@@ -549,4 +666,9 @@ class TransientBubbleStashController(
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun BubbleBarLocation.isSameSideWith(anotherLocation: BubbleBarLocation): Boolean {
|
||||
val isRtl = context.isRtl
|
||||
return this.isOnLeft(isRtl) == anotherLocation.isOnLeft(isRtl)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user