Implement API to animate bubble bar position
Create a new API to animate bubble bar position. Animating it will not update its laid out location. To update bubble bar laid out location, BubbleBarUpdate can be used. Applying a location change from BubbleBarUpdate no longer animates the change. Bug: 330585402 Flag: ACONFIG com.android.wm.shell.enable_bubble_bar DEVELOPMENT Test: long press bubble bar and drag it to left and right Change-Id: I2572da4c063fc8e07cf07c4303778d343baa4ec4
This commit is contained in:
@@ -419,9 +419,7 @@ public class BubbleBarController extends IBubblesListener.Stub {
|
||||
}
|
||||
if (update.bubbleBarLocation != null) {
|
||||
if (update.bubbleBarLocation != mBubbleBarViewController.getBubbleBarLocation()) {
|
||||
// Animate when receiving updates. Skip it if we received the initial state.
|
||||
boolean animate = !update.initialState;
|
||||
updateBubbleBarLocationInternal(update.bubbleBarLocation, animate);
|
||||
updateBubbleBarLocationInternal(update.bubbleBarLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -483,15 +481,21 @@ public class BubbleBarController extends IBubblesListener.Stub {
|
||||
* Updates the value locally in Launcher and in WMShell.
|
||||
*/
|
||||
public void updateBubbleBarLocation(BubbleBarLocation location) {
|
||||
updateBubbleBarLocationInternal(location, false /* animate */);
|
||||
updateBubbleBarLocationInternal(location);
|
||||
mSystemUiProxy.setBubbleBarLocation(location);
|
||||
}
|
||||
|
||||
private void updateBubbleBarLocationInternal(BubbleBarLocation location, boolean animate) {
|
||||
mBubbleBarViewController.setBubbleBarLocation(location, animate);
|
||||
private void updateBubbleBarLocationInternal(BubbleBarLocation location) {
|
||||
mBubbleBarViewController.setBubbleBarLocation(location);
|
||||
mBubbleStashController.setBubbleBarLocation(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animateBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
mMainExecutor.execute(
|
||||
() -> mBubbleBarViewController.animateBubbleBarLocation(bubbleBarLocation));
|
||||
}
|
||||
|
||||
//
|
||||
// Loading data for the bubbles
|
||||
//
|
||||
|
||||
@@ -153,8 +153,6 @@ public class BubbleBarView extends FrameLayout {
|
||||
|
||||
private int mPreviousLayoutDirection = LayoutDirection.UNDEFINED;
|
||||
|
||||
private boolean mLocationChangePending;
|
||||
|
||||
public BubbleBarView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -188,7 +186,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
|
||||
mWidthAnimator.setDuration(WIDTH_ANIMATION_DURATION_MS);
|
||||
mWidthAnimator.addUpdateListener(animation -> {
|
||||
updateChildrenRenderNodeProperties();
|
||||
updateChildrenRenderNodeProperties(mBubbleBarLocation);
|
||||
invalidate();
|
||||
});
|
||||
mWidthAnimator.addListener(new Animator.AnimatorListener() {
|
||||
@@ -262,7 +260,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
setPivotY(mRelativePivotY * getHeight());
|
||||
|
||||
// Position the views
|
||||
updateChildrenRenderNodeProperties();
|
||||
updateChildrenRenderNodeProperties(mBubbleBarLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -278,7 +276,6 @@ public class BubbleBarView extends FrameLayout {
|
||||
|
||||
@SuppressLint("RtlHardcoded")
|
||||
private void onBubbleBarLocationChanged() {
|
||||
mLocationChangePending = false;
|
||||
final boolean onLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
|
||||
mBubbleBarBackground.setAnchorLeft(onLeft);
|
||||
mRelativePivotX = onLeft ? 0f : 1f;
|
||||
@@ -299,11 +296,18 @@ public class BubbleBarView extends FrameLayout {
|
||||
/**
|
||||
* Update {@link BubbleBarLocation}
|
||||
*/
|
||||
public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, boolean animate) {
|
||||
if (animate) {
|
||||
animateToBubbleBarLocation(bubbleBarLocation);
|
||||
} else {
|
||||
setBubbleBarLocationInternal(bubbleBarLocation);
|
||||
public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
if (mBubbleBarLocationAnimator != null) {
|
||||
mBubbleBarLocationAnimator.removeAllListeners();
|
||||
mBubbleBarLocationAnimator.cancel();
|
||||
mBubbleBarLocationAnimator = null;
|
||||
}
|
||||
setTranslationX(0f);
|
||||
setAlpha(1f);
|
||||
if (bubbleBarLocation != mBubbleBarLocation) {
|
||||
mBubbleBarLocation = bubbleBarLocation;
|
||||
onBubbleBarLocationChanged();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,51 +320,37 @@ public class BubbleBarView extends FrameLayout {
|
||||
}
|
||||
mDragging = dragging;
|
||||
setElevation(dragging ? mDragElevation : mBubbleElevation);
|
||||
if (!dragging && mLocationChangePending) {
|
||||
// During drag finish animation we may update the translation x value to shift the
|
||||
// bubble to the new drop target. Clear the translation here.
|
||||
setTranslationX(0f);
|
||||
onBubbleBarLocationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust resting position for the bubble bar while it is being dragged.
|
||||
* <p>
|
||||
* Bubble bar is laid out on left or right side of the screen. When it is being dragged to
|
||||
* the opposite side, the resting position should be on that side. Calculate any additional
|
||||
* translation that may be required to move the bubble bar to the new side.
|
||||
* Get translation for bubble bar when drag is released and it needs to animate back to the
|
||||
* resting position.
|
||||
* Resting position is based on the supplied location. If the supplied location is different
|
||||
* from the internal location that was used to lay out the bubble bar, translation values are
|
||||
* calculated to position the bar at the desired location.
|
||||
*
|
||||
* @param restingPosition relative resting position of the bubble bar from the laid out position
|
||||
* @param initialTranslation initial bubble bar translation at the start of drag
|
||||
* @param location desired location of the bubble bar when drag is released
|
||||
* @return point with x and y values representing translation on x and y-axis
|
||||
*/
|
||||
@SuppressLint("RtlHardcoded")
|
||||
void adjustRelativeRestingPosition(PointF restingPosition) {
|
||||
final boolean locationOnLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
|
||||
// Bubble bar is placed left or right with gravity. Check where it is currently.
|
||||
final int absoluteGravity = Gravity.getAbsoluteGravity(
|
||||
((LayoutParams) getLayoutParams()).gravity, getLayoutDirection());
|
||||
final boolean gravityOnLeft =
|
||||
(absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT;
|
||||
|
||||
// Bubble bar is pinned to the same side per gravity and the desired location.
|
||||
// Resting translation does not need to be adjusted.
|
||||
if (locationOnLeft == gravityOnLeft) {
|
||||
return;
|
||||
}
|
||||
|
||||
public PointF getBubbleBarDragReleaseTranslation(PointF initialTranslation,
|
||||
BubbleBarLocation location) {
|
||||
// Start with the initial translation. Value on y-axis can be reused.
|
||||
final PointF dragEndTranslation = new PointF(initialTranslation);
|
||||
// Bubble bar is laid out on left or right side of the screen. And the desired new
|
||||
// location is on the other side. Calculate x translation value required to shift the
|
||||
// location is on the other side. Calculate x translation value required to shift
|
||||
// bubble bar from one side to the other.
|
||||
float x = getDistanceFromOtherSide();
|
||||
if (locationOnLeft) {
|
||||
final float shift = getDistanceFromOtherSide();
|
||||
if (location.isOnLeft(isLayoutRtl())) {
|
||||
// New location is on the left, shift left
|
||||
// before -> |......ooo.| after -> |.ooo......|
|
||||
restingPosition.x = -x;
|
||||
dragEndTranslation.x = -shift;
|
||||
} else {
|
||||
// New location is on the right, shift right
|
||||
// before -> |.ooo......| after -> |......ooo.|
|
||||
restingPosition.x = x;
|
||||
dragEndTranslation.x = shift;
|
||||
}
|
||||
return dragEndTranslation;
|
||||
}
|
||||
|
||||
private float getDistanceFromOtherSide() {
|
||||
@@ -374,49 +364,40 @@ public class BubbleBarView extends FrameLayout {
|
||||
return (float) (displayWidth - getWidth() - margin);
|
||||
}
|
||||
|
||||
private void setBubbleBarLocationInternal(BubbleBarLocation bubbleBarLocation) {
|
||||
if (bubbleBarLocation != mBubbleBarLocation) {
|
||||
mBubbleBarLocation = bubbleBarLocation;
|
||||
if (mDragging) {
|
||||
mLocationChangePending = true;
|
||||
} else {
|
||||
onBubbleBarLocationChanged();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void animateToBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
if (bubbleBarLocation == mBubbleBarLocation) {
|
||||
// nothing to do, already at expected location
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Animate bubble bar to the given location transiently. Does not modify the layout or the value
|
||||
* returned by {@link #getBubbleBarLocation()}.
|
||||
*/
|
||||
public void animateToBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
if (mBubbleBarLocationAnimator != null && mBubbleBarLocationAnimator.isRunning()) {
|
||||
mBubbleBarLocationAnimator.removeAllListeners();
|
||||
mBubbleBarLocationAnimator.cancel();
|
||||
}
|
||||
|
||||
// Location animation uses two separate animators.
|
||||
// First animator hides the bar.
|
||||
// After it completes, location update is sent to layout the bar in the new location.
|
||||
// After it completes, bubble positions in the bar and arrow position is updated.
|
||||
// Second animator is started to show the bar.
|
||||
mBubbleBarLocationAnimator = getLocationUpdateFadeOutAnimator();
|
||||
mBubbleBarLocationAnimator = getLocationUpdateFadeOutAnimator(bubbleBarLocation);
|
||||
mBubbleBarLocationAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
// Bubble bar is not visible, update the location
|
||||
setBubbleBarLocationInternal(bubbleBarLocation);
|
||||
updateChildrenRenderNodeProperties(bubbleBarLocation);
|
||||
mBubbleBarBackground.setAnchorLeft(bubbleBarLocation.isOnLeft(isLayoutRtl()));
|
||||
|
||||
// Animate it in
|
||||
mBubbleBarLocationAnimator = getLocationUpdateFadeInAnimator();
|
||||
mBubbleBarLocationAnimator = getLocationUpdateFadeInAnimator(bubbleBarLocation);
|
||||
mBubbleBarLocationAnimator.start();
|
||||
}
|
||||
});
|
||||
mBubbleBarLocationAnimator.start();
|
||||
}
|
||||
|
||||
private AnimatorSet getLocationUpdateFadeOutAnimator() {
|
||||
private Animator getLocationUpdateFadeOutAnimator(BubbleBarLocation bubbleBarLocation) {
|
||||
final float shift =
|
||||
getResources().getDisplayMetrics().widthPixels * FADE_OUT_ANIM_POSITION_SHIFT;
|
||||
final float tx = mBubbleBarLocation.isOnLeft(isLayoutRtl()) ? shift : -shift;
|
||||
final boolean onLeft = bubbleBarLocation.isOnLeft(isLayoutRtl());
|
||||
final float tx = getTranslationX() + (onLeft ? shift : -shift);
|
||||
|
||||
ObjectAnimator positionAnim = ObjectAnimator.ofFloat(this, TRANSLATION_X, tx)
|
||||
.setDuration(FADE_OUT_ANIM_POSITION_DURATION_MS);
|
||||
@@ -431,14 +412,31 @@ public class BubbleBarView extends FrameLayout {
|
||||
return animatorSet;
|
||||
}
|
||||
|
||||
private Animator getLocationUpdateFadeInAnimator() {
|
||||
private Animator getLocationUpdateFadeInAnimator(BubbleBarLocation animatedLocation) {
|
||||
final float shift =
|
||||
getResources().getDisplayMetrics().widthPixels * FADE_IN_ANIM_POSITION_SHIFT;
|
||||
final float startTx = mBubbleBarLocation.isOnLeft(isLayoutRtl()) ? shift : -shift;
|
||||
|
||||
final boolean onLeft = animatedLocation.isOnLeft(isLayoutRtl());
|
||||
final float startTx;
|
||||
final float finalTx;
|
||||
if (animatedLocation == mBubbleBarLocation) {
|
||||
// Animated location matches layout location.
|
||||
finalTx = 0;
|
||||
} else {
|
||||
// We are animating in to a transient location, need to move the bar accordingly.
|
||||
finalTx = getDistanceFromOtherSide() * (onLeft ? -1 : 1);
|
||||
}
|
||||
if (onLeft) {
|
||||
// Bar will be shown on the left side. Start point is shifted right.
|
||||
startTx = finalTx + shift;
|
||||
} else {
|
||||
// Bar will be shown on the right side. Start point is shifted left.
|
||||
startTx = finalTx - shift;
|
||||
}
|
||||
|
||||
ValueAnimator positionAnim = new SpringAnimationBuilder(getContext())
|
||||
.setStartValue(startTx)
|
||||
.setEndValue(0)
|
||||
.setEndValue(finalTx)
|
||||
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
|
||||
.setStiffness(FADE_IN_ANIM_POSITION_SPRING_STIFFNESS)
|
||||
.build(this, VIEW_TRANSLATE_X);
|
||||
@@ -547,7 +545,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
* Updates the z order, positions, and badge visibility of the bubble views in the bar based
|
||||
* on the expanded state.
|
||||
*/
|
||||
private void updateChildrenRenderNodeProperties() {
|
||||
private void updateChildrenRenderNodeProperties(BubbleBarLocation bubbleBarLocation) {
|
||||
final float widthState = (float) mWidthAnimator.getAnimatedValue();
|
||||
final float currentWidth = getWidth();
|
||||
final float expandedWidth = expandedWidth();
|
||||
@@ -555,7 +553,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
int bubbleCount = getChildCount();
|
||||
final float ty = (mBubbleBarBounds.height() - mIconSize) / 2f;
|
||||
final boolean animate = getVisibility() == VISIBLE;
|
||||
final boolean onLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
|
||||
final boolean onLeft = bubbleBarLocation.isOnLeft(isLayoutRtl());
|
||||
// elevation state is opposite to widthState - when expanded all icons are flat
|
||||
float elevationState = (1 - widthState);
|
||||
for (int i = 0; i < bubbleCount; i++) {
|
||||
@@ -613,8 +611,9 @@ public class BubbleBarView extends FrameLayout {
|
||||
}
|
||||
|
||||
// update the arrow position
|
||||
final float collapsedArrowPosition = arrowPositionForSelectedWhenCollapsed();
|
||||
final float expandedArrowPosition = arrowPositionForSelectedWhenExpanded();
|
||||
final float collapsedArrowPosition = arrowPositionForSelectedWhenCollapsed(
|
||||
bubbleBarLocation);
|
||||
final float expandedArrowPosition = arrowPositionForSelectedWhenExpanded(bubbleBarLocation);
|
||||
final float interpolatedWidth =
|
||||
widthState * (expandedWidth - collapsedWidth) + collapsedWidth;
|
||||
final float arrowPosition;
|
||||
@@ -661,7 +660,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
addViewInLayout(child, i, child.getLayoutParams());
|
||||
}
|
||||
}
|
||||
updateChildrenRenderNodeProperties();
|
||||
updateChildrenRenderNodeProperties(mBubbleBarLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,7 +701,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
// Find the center of the bubble when it's expanded, set the arrow position to it.
|
||||
final float tx = arrowPositionForSelectedWhenExpanded();
|
||||
final float tx = arrowPositionForSelectedWhenExpanded(mBubbleBarLocation);
|
||||
final float currentArrowPosition = mBubbleBarBackground.getArrowPositionX();
|
||||
if (tx == currentArrowPosition) {
|
||||
// arrow position remains unchanged
|
||||
@@ -727,10 +726,10 @@ public class BubbleBarView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private float arrowPositionForSelectedWhenExpanded() {
|
||||
private float arrowPositionForSelectedWhenExpanded(BubbleBarLocation bubbleBarLocation) {
|
||||
final int index = indexOfChild(mSelectedBubbleView);
|
||||
final int bubblePosition;
|
||||
if (mBubbleBarLocation.isOnLeft(isLayoutRtl())) {
|
||||
if (bubbleBarLocation.isOnLeft(isLayoutRtl())) {
|
||||
// Bubble positions are reversed. First bubble is on the right.
|
||||
bubblePosition = getChildCount() - index - 1;
|
||||
} else {
|
||||
@@ -740,10 +739,10 @@ public class BubbleBarView extends FrameLayout {
|
||||
+ mIconSize / 2f;
|
||||
}
|
||||
|
||||
private float arrowPositionForSelectedWhenCollapsed() {
|
||||
private float arrowPositionForSelectedWhenCollapsed(BubbleBarLocation bubbleBarLocation) {
|
||||
final int index = indexOfChild(mSelectedBubbleView);
|
||||
final int bubblePosition;
|
||||
if (mBubbleBarLocation.isOnLeft(isLayoutRtl())) {
|
||||
if (bubbleBarLocation.isOnLeft(isLayoutRtl())) {
|
||||
// Bubble positions are reversed. First bubble may be shifted, if there are more
|
||||
// bubbles than the current bubble and overflow.
|
||||
bubblePosition = index == 0 && getChildCount() > 2 ? 1 : 0;
|
||||
|
||||
@@ -215,8 +215,17 @@ public class BubbleBarViewController {
|
||||
/**
|
||||
* Update bar {@link BubbleBarLocation}
|
||||
*/
|
||||
public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, boolean animate) {
|
||||
mBarView.setBubbleBarLocation(bubbleBarLocation, animate);
|
||||
public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
mBarView.setBubbleBarLocation(bubbleBarLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate bubble bar to the given location. The location change is transient. It does not
|
||||
* update the state of the bubble bar.
|
||||
* To update bubble bar pinned location, use {@link #setBubbleBarLocation(BubbleBarLocation)}.
|
||||
*/
|
||||
public void animateBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
mBarView.animateToBubbleBarLocation(bubbleBarLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,25 +110,25 @@ public class BubbleDragAnimator {
|
||||
/**
|
||||
* Animates the dragged bubble movement back to the initial position.
|
||||
*
|
||||
* @param initialPosition the position to animate to
|
||||
* @param restingPosition the position to animate to
|
||||
* @param velocity the initial velocity to use for the spring animation
|
||||
* @param endActions gets called when the animation completes or gets cancelled
|
||||
*/
|
||||
public void animateToInitialState(@NonNull PointF initialPosition, @NonNull PointF velocity,
|
||||
public void animateToRestingState(@NonNull PointF restingPosition, @NonNull PointF velocity,
|
||||
@Nullable Runnable endActions) {
|
||||
mBubbleAnimator.cancel();
|
||||
mBubbleAnimator
|
||||
.spring(DynamicAnimation.SCALE_X, 1f)
|
||||
.spring(DynamicAnimation.SCALE_Y, 1f)
|
||||
.spring(DynamicAnimation.TRANSLATION_X, initialPosition.x, velocity.x,
|
||||
.spring(DynamicAnimation.TRANSLATION_X, restingPosition.x, velocity.x,
|
||||
mTranslationConfig)
|
||||
.spring(DynamicAnimation.TRANSLATION_Y, initialPosition.y, velocity.y,
|
||||
.spring(DynamicAnimation.TRANSLATION_Y, restingPosition.y, velocity.y,
|
||||
mTranslationConfig)
|
||||
.addEndListener((View target, @NonNull FloatPropertyCompat<? super View> property,
|
||||
boolean wasFling, boolean canceled, float finalValue, float finalVelocity,
|
||||
boolean allRelevantPropertyAnimationsEnded) -> {
|
||||
if (canceled || allRelevantPropertyAnimationsEnded) {
|
||||
resetAnimatedViews(initialPosition);
|
||||
resetAnimatedViews(restingPosition);
|
||||
if (endActions != null) {
|
||||
endActions.run();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
import com.android.wm.shell.common.bubbles.BaseBubblePinController.LocationChangeListener;
|
||||
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
|
||||
|
||||
/**
|
||||
* Controls bubble bar drag interactions.
|
||||
@@ -37,6 +39,7 @@ import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
*/
|
||||
public class BubbleDragController {
|
||||
private final TaskbarActivityContext mActivity;
|
||||
private BubbleBarController mBubbleBarController;
|
||||
private BubbleBarViewController mBubbleBarViewController;
|
||||
private BubbleDismissController mBubbleDismissController;
|
||||
private BubbleBarPinController mBubbleBarPinController;
|
||||
@@ -51,11 +54,10 @@ public class BubbleDragController {
|
||||
* controllers may still be waiting for init().
|
||||
*/
|
||||
public void init(@NonNull BubbleControllers bubbleControllers) {
|
||||
mBubbleBarController = bubbleControllers.bubbleBarController;
|
||||
mBubbleBarViewController = bubbleControllers.bubbleBarViewController;
|
||||
mBubbleDismissController = bubbleControllers.bubbleDismissController;
|
||||
mBubbleBarPinController = bubbleControllers.bubbleBarPinController;
|
||||
mBubbleBarPinController.setListener(
|
||||
bubbleControllers.bubbleBarController::updateBubbleBarLocation);
|
||||
mBubbleDismissController.setListener(
|
||||
stuck -> mBubbleBarPinController.setDropTargetHidden(stuck));
|
||||
}
|
||||
@@ -96,6 +98,17 @@ public class BubbleDragController {
|
||||
PointF initialRelativePivot = new PointF();
|
||||
bubbleBarView.setOnTouchListener(new BubbleTouchListener() {
|
||||
|
||||
@Nullable
|
||||
private BubbleBarLocation mReleasedLocation;
|
||||
|
||||
private final LocationChangeListener mLocationChangeListener =
|
||||
new LocationChangeListener() {
|
||||
@Override
|
||||
public void onRelease(@NonNull BubbleBarLocation location) {
|
||||
mReleasedLocation = location;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected boolean onTouchDown(@NonNull View view, @NonNull MotionEvent event) {
|
||||
if (bubbleBarView.isExpanded()) return false;
|
||||
@@ -104,6 +117,7 @@ public class BubbleDragController {
|
||||
|
||||
@Override
|
||||
void onDragStart() {
|
||||
mBubbleBarPinController.setListener(mLocationChangeListener);
|
||||
initialRelativePivot.set(bubbleBarView.getRelativePivotX(),
|
||||
bubbleBarView.getRelativePivotY());
|
||||
// By default the bubble bar view pivot is in bottom right corner, while dragging
|
||||
@@ -134,13 +148,17 @@ public class BubbleDragController {
|
||||
// Restoring the initial pivot for the bubble bar view
|
||||
bubbleBarView.setRelativePivot(initialRelativePivot.x, initialRelativePivot.y);
|
||||
bubbleBarView.setIsDragging(false);
|
||||
mBubbleBarController.updateBubbleBarLocation(mReleasedLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PointF getRestingPosition() {
|
||||
PointF restingPosition = super.getRestingPosition();
|
||||
bubbleBarView.adjustRelativeRestingPosition(restingPosition);
|
||||
return restingPosition;
|
||||
if (mReleasedLocation == null
|
||||
|| mReleasedLocation == bubbleBarView.getBubbleBarLocation()) {
|
||||
return getInitialPosition();
|
||||
}
|
||||
return bubbleBarView.getBubbleBarDragReleaseTranslation(getInitialPosition(),
|
||||
mReleasedLocation);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -228,6 +246,13 @@ public class BubbleDragController {
|
||||
protected void onDragDismiss() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the initial position of the view when drag started
|
||||
*/
|
||||
protected PointF getInitialPosition() {
|
||||
return mViewInitialPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resting position of the view when drag is released
|
||||
*/
|
||||
@@ -362,7 +387,7 @@ public class BubbleDragController {
|
||||
mAnimator.animateDismiss(mViewInitialPosition, onComplete);
|
||||
} else {
|
||||
onDragRelease();
|
||||
mAnimator.animateToInitialState(getRestingPosition(), getCurrentVelocity(),
|
||||
mAnimator.animateToRestingState(getRestingPosition(), getCurrentVelocity(),
|
||||
onComplete);
|
||||
}
|
||||
mBubbleDismissController.hideDismissView();
|
||||
|
||||
Reference in New Issue
Block a user