Merge "Avoid bad animation states." into rvc-dev am: 5bef1eb6da
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11854105 Change-Id: I0dc95e555fac32a781b38be0a916564ac7c1b3a1
This commit is contained in:
@@ -49,6 +49,7 @@ import android.graphics.RectF;
|
|||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.graphics.drawable.TransitionDrawable;
|
import android.graphics.drawable.TransitionDrawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Choreographer;
|
import android.view.Choreographer;
|
||||||
@@ -158,6 +159,12 @@ public class BubbleStackView extends FrameLayout
|
|||||||
new PhysicsAnimator.SpringConfig(
|
new PhysicsAnimator.SpringConfig(
|
||||||
SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_NO_BOUNCY);
|
SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_NO_BOUNCY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to use for all delayed animations - this way, we can easily cancel them before
|
||||||
|
* starting a new animation.
|
||||||
|
*/
|
||||||
|
private final Handler mDelayedAnimationHandler = new Handler();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to synchronize {@link View} state and the screen.
|
* Interface to synchronize {@link View} state and the screen.
|
||||||
*
|
*
|
||||||
@@ -292,6 +299,7 @@ public class BubbleStackView extends FrameLayout
|
|||||||
|
|
||||||
private boolean mViewUpdatedRequested = false;
|
private boolean mViewUpdatedRequested = false;
|
||||||
private boolean mIsExpansionAnimating = false;
|
private boolean mIsExpansionAnimating = false;
|
||||||
|
private boolean mIsBubbleSwitchAnimating = false;
|
||||||
private boolean mShowingDismiss = false;
|
private boolean mShowingDismiss = false;
|
||||||
|
|
||||||
/** The view to desaturate/darken when magneted to the dismiss target. */
|
/** The view to desaturate/darken when magneted to the dismiss target. */
|
||||||
@@ -469,6 +477,13 @@ public class BubbleStackView extends FrameLayout
|
|||||||
private OnClickListener mBubbleClickListener = new OnClickListener() {
|
private OnClickListener mBubbleClickListener = new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
// Bubble clicks either trigger expansion/collapse or a bubble switch, both of which we
|
||||||
|
// shouldn't interrupt. These are quick transitions, so it's not worth trying to adjust
|
||||||
|
// the animations inflight.
|
||||||
|
if (mIsExpansionAnimating || mIsBubbleSwitchAnimating) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final Bubble clickedBubble = mBubbleData.getBubbleWithView(view);
|
final Bubble clickedBubble = mBubbleData.getBubbleWithView(view);
|
||||||
|
|
||||||
// If the bubble has since left us, ignore the click.
|
// If the bubble has since left us, ignore the click.
|
||||||
@@ -1732,6 +1747,8 @@ public class BubbleStackView extends FrameLayout
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void animateExpansion() {
|
private void animateExpansion() {
|
||||||
|
cancelDelayedExpandCollapseSwitchAnimations();
|
||||||
|
|
||||||
mIsExpanded = true;
|
mIsExpanded = true;
|
||||||
hideStackUserEducation(true /* fromExpansion */);
|
hideStackUserEducation(true /* fromExpansion */);
|
||||||
beforeExpandedViewAnimation();
|
beforeExpandedViewAnimation();
|
||||||
@@ -1780,37 +1797,43 @@ public class BubbleStackView extends FrameLayout
|
|||||||
mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
|
mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
postDelayed(() -> PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
|
mDelayedAnimationHandler.postDelayed(() ->
|
||||||
.spring(AnimatableScaleMatrix.SCALE_X,
|
PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
|
||||||
AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
|
.spring(AnimatableScaleMatrix.SCALE_X,
|
||||||
mScaleInSpringConfig)
|
AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
|
||||||
.spring(AnimatableScaleMatrix.SCALE_Y,
|
mScaleInSpringConfig)
|
||||||
AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
|
.spring(AnimatableScaleMatrix.SCALE_Y,
|
||||||
mScaleInSpringConfig)
|
AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
|
||||||
.addUpdateListener((target, values) -> {
|
mScaleInSpringConfig)
|
||||||
if (mExpandedBubble.getIconView() == null) {
|
.addUpdateListener((target, values) -> {
|
||||||
return;
|
if (mExpandedBubble.getIconView() == null) {
|
||||||
}
|
return;
|
||||||
mExpandedViewContainerMatrix.postTranslate(
|
}
|
||||||
mExpandedBubble.getIconView().getTranslationX()
|
mExpandedViewContainerMatrix.postTranslate(
|
||||||
- bubbleWillBeAtX,
|
mExpandedBubble.getIconView().getTranslationX()
|
||||||
0);
|
- bubbleWillBeAtX,
|
||||||
mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
|
0);
|
||||||
})
|
mExpandedViewContainer.setAnimationMatrix(
|
||||||
.withEndActions(() -> {
|
mExpandedViewContainerMatrix);
|
||||||
if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
|
})
|
||||||
mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
|
.withEndActions(() -> {
|
||||||
}
|
if (mExpandedBubble != null
|
||||||
})
|
&& mExpandedBubble.getExpandedView() != null) {
|
||||||
.start(), startDelay);
|
mExpandedBubble.getExpandedView()
|
||||||
|
.setSurfaceZOrderedOnTop(false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.start(), startDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void animateCollapse() {
|
private void animateCollapse() {
|
||||||
|
cancelDelayedExpandCollapseSwitchAnimations();
|
||||||
|
|
||||||
// Hide the menu if it's visible.
|
// Hide the menu if it's visible.
|
||||||
showManageMenu(false);
|
showManageMenu(false);
|
||||||
|
|
||||||
mIsExpanded = false;
|
mIsExpanded = false;
|
||||||
|
mIsExpansionAnimating = true;
|
||||||
|
|
||||||
mBubbleContainer.cancelAllAnimations();
|
mBubbleContainer.cancelAllAnimations();
|
||||||
|
|
||||||
@@ -1830,12 +1853,10 @@ public class BubbleStackView extends FrameLayout
|
|||||||
|
|
||||||
final long startDelay =
|
final long startDelay =
|
||||||
(long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 0.6f);
|
(long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 0.6f);
|
||||||
postDelayed(() -> mExpandedAnimationController.collapseBackToStack(
|
mDelayedAnimationHandler.postDelayed(() -> mExpandedAnimationController.collapseBackToStack(
|
||||||
mStackAnimationController.getStackPositionAlongNearestHorizontalEdge()
|
mStackAnimationController.getStackPositionAlongNearestHorizontalEdge()
|
||||||
/* collapseTo */,
|
/* collapseTo */,
|
||||||
() -> {
|
() -> mBubbleContainer.setActiveController(mStackAnimationController)), startDelay);
|
||||||
mBubbleContainer.setActiveController(mStackAnimationController);
|
|
||||||
}), startDelay);
|
|
||||||
|
|
||||||
// We want to visually collapse into this bubble during the animation.
|
// We want to visually collapse into this bubble during the animation.
|
||||||
final View expandingFromBubble = mExpandedBubble.getIconView();
|
final View expandingFromBubble = mExpandedBubble.getIconView();
|
||||||
@@ -1890,6 +1911,13 @@ public class BubbleStackView extends FrameLayout
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void animateSwitchBubbles() {
|
private void animateSwitchBubbles() {
|
||||||
|
// If we're no longer expanded, this is meaningless.
|
||||||
|
if (!mIsExpanded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mIsBubbleSwitchAnimating = true;
|
||||||
|
|
||||||
// The surface contains a screenshot of the animating out bubble, so we just need to animate
|
// The surface contains a screenshot of the animating out bubble, so we just need to animate
|
||||||
// it out (and then release the GraphicBuffer).
|
// it out (and then release the GraphicBuffer).
|
||||||
PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer).cancel();
|
PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer).cancel();
|
||||||
@@ -1915,8 +1943,9 @@ public class BubbleStackView extends FrameLayout
|
|||||||
0f, 0f, expandingFromBubbleDestinationX + mBubbleSize / 2f, getExpandedViewY());
|
0f, 0f, expandingFromBubbleDestinationX + mBubbleSize / 2f, getExpandedViewY());
|
||||||
mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
|
mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
|
||||||
|
|
||||||
mExpandedViewContainer.postDelayed(() -> {
|
mDelayedAnimationHandler.postDelayed(() -> {
|
||||||
if (!mIsExpanded) {
|
if (!mIsExpanded) {
|
||||||
|
mIsBubbleSwitchAnimating = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1934,11 +1963,24 @@ public class BubbleStackView extends FrameLayout
|
|||||||
if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
|
if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
|
||||||
mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
|
mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mIsBubbleSwitchAnimating = false;
|
||||||
})
|
})
|
||||||
.start();
|
.start();
|
||||||
}, 25);
|
}, 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels any delayed steps for expand/collapse and bubble switch animations, and resets the is
|
||||||
|
* animating flags for those animations.
|
||||||
|
*/
|
||||||
|
private void cancelDelayedExpandCollapseSwitchAnimations() {
|
||||||
|
mDelayedAnimationHandler.removeCallbacksAndMessages(null);
|
||||||
|
|
||||||
|
mIsExpansionAnimating = false;
|
||||||
|
mIsBubbleSwitchAnimating = false;
|
||||||
|
}
|
||||||
|
|
||||||
private void notifyExpansionChanged(BubbleViewProvider bubble, boolean expanded) {
|
private void notifyExpansionChanged(BubbleViewProvider bubble, boolean expanded) {
|
||||||
if (mExpandListener != null && bubble != null) {
|
if (mExpandListener != null && bubble != null) {
|
||||||
mExpandListener.onBubbleExpandChanged(expanded, bubble.getKey());
|
mExpandListener.onBubbleExpandChanged(expanded, bubble.getKey());
|
||||||
|
|||||||
Reference in New Issue
Block a user