Merge "Fixes positioning issues with the bubble stack."

This commit is contained in:
Josh Tsuji
2019-02-14 19:35:42 +00:00
committed by Android (Google) Code Review
3 changed files with 68 additions and 59 deletions

View File

@@ -98,6 +98,7 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
private int mBubblePadding;
private int mExpandedAnimateXDistance;
private int mExpandedAnimateYDistance;
private int mStatusBarHeight;
private Bubble mExpandedBubble;
private boolean mIsExpanded;
@@ -155,6 +156,8 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
res.getDimensionPixelSize(R.dimen.bubble_expanded_animate_x_distance);
mExpandedAnimateYDistance =
res.getDimensionPixelSize(R.dimen.bubble_expanded_animate_y_distance);
mStatusBarHeight =
res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
mDisplaySize = new Point();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -678,7 +681,7 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
if (getRootWindowInsets() != null) {
WindowInsets insets = getRootWindowInsets();
return Math.max(
insets.getSystemWindowInsetTop(),
mStatusBarHeight,
insets.getDisplayCutout() != null
? insets.getDisplayCutout().getSafeInsetTop()
: 0);

View File

@@ -16,6 +16,7 @@
package com.android.systemui.bubbles.animation;
import android.content.res.Resources;
import android.graphics.PointF;
import android.view.View;
import android.view.WindowInsets;
@@ -55,16 +56,19 @@ public class ExpandedAnimationController
private float mBubblePaddingPx;
/** Size of each bubble. */
private float mBubbleSizePx;
/** Height of the status bar. */
private float mStatusBarHeight;
@Override
protected void setLayout(PhysicsAnimationLayout layout) {
super.setLayout(layout);
mStackOffsetPx = layout.getResources().getDimensionPixelSize(
R.dimen.bubble_stack_offset);
mBubblePaddingPx = layout.getResources().getDimensionPixelSize(
R.dimen.bubble_padding);
mBubbleSizePx = layout.getResources().getDimensionPixelSize(
R.dimen.individual_bubble_size);
final Resources res = layout.getResources();
mStackOffsetPx = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
mBubblePaddingPx = res.getDimensionPixelSize(R.dimen.bubble_padding);
mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
mStatusBarHeight =
res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
}
/**
@@ -103,7 +107,7 @@ public class ExpandedAnimationController
final WindowInsets insets = mLayout.getRootWindowInsets();
if (insets != null) {
return mBubblePaddingPx + Math.max(
insets.getSystemWindowInsetTop(),
mStatusBarHeight,
insets.getDisplayCutout() != null
? insets.getDisplayCutout().getSafeInsetTop()
: 0);

View File

@@ -16,15 +16,12 @@
package com.android.systemui.bubbles.animation;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.Log;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.FlingAnimation;
@@ -88,9 +85,8 @@ public class StackAnimationController extends
private int mBubbleOffscreen;
/** How far down the screen the stack starts, when there is no pre-existing location. */
private int mStackStartingVerticalOffset;
private Point mDisplaySize;
private RectF mAllowableStackPositionRegion;
/** Height of the status bar. */
private float mStatusBarHeight;
@Override
protected void setLayout(PhysicsAnimationLayout layout) {
@@ -103,11 +99,8 @@ public class StackAnimationController extends
mBubbleOffscreen = res.getDimensionPixelSize(R.dimen.bubble_stack_offscreen);
mStackStartingVerticalOffset =
res.getDimensionPixelSize(R.dimen.bubble_stack_starting_offset_y);
mDisplaySize = new Point();
WindowManager wm =
(WindowManager) layout.getContext().getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getSize(mDisplaySize);
mStatusBarHeight =
res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
}
/**
@@ -203,10 +196,9 @@ public class StackAnimationController extends
*/
public RectF getAllowableStackPositionRegion() {
final WindowInsets insets = mLayout.getRootWindowInsets();
mAllowableStackPositionRegion = new RectF();
final RectF allowableRegion = new RectF();
if (insets != null) {
mAllowableStackPositionRegion.left =
allowableRegion.left =
-mBubbleOffscreen
- mBubblePadding
+ Math.max(
@@ -214,7 +206,7 @@ public class StackAnimationController extends
insets.getDisplayCutout() != null
? insets.getDisplayCutout().getSafeInsetLeft()
: 0);
mAllowableStackPositionRegion.right =
allowableRegion.right =
mLayout.getWidth()
- mIndividualBubbleSize
+ mBubbleOffscreen
@@ -222,17 +214,17 @@ public class StackAnimationController extends
- Math.max(
insets.getSystemWindowInsetRight(),
insets.getDisplayCutout() != null
? insets.getDisplayCutout().getSafeInsetRight()
: 0);
? insets.getDisplayCutout().getSafeInsetRight()
: 0);
mAllowableStackPositionRegion.top =
allowableRegion.top =
mBubblePadding
+ Math.max(
insets.getSystemWindowInsetTop(),
mStatusBarHeight,
insets.getDisplayCutout() != null
? insets.getDisplayCutout().getSafeInsetTop()
: 0);
mAllowableStackPositionRegion.bottom =
? insets.getDisplayCutout().getSafeInsetTop()
: 0);
allowableRegion.bottom =
mLayout.getHeight()
- mIndividualBubbleSize
- mBubblePadding
@@ -243,7 +235,7 @@ public class StackAnimationController extends
: 0);
}
return mAllowableStackPositionRegion;
return allowableRegion;
}
@Override
@@ -287,31 +279,14 @@ public class StackAnimationController extends
@Override
void onChildAdded(View child, int index) {
// If this is the first child added, position the stack in its starting position.
if (mLayout.getChildCount() == 1) {
moveStackToStartPosition();
}
if (mLayout.indexOfChild(child) == 0) {
child.setTranslationY(mStackPosition.y);
// Pop in the new bubble.
child.setScaleX(ANIMATE_IN_STARTING_SCALE);
child.setScaleY(ANIMATE_IN_STARTING_SCALE);
mLayout.animateValueForChildAtIndex(DynamicAnimation.SCALE_X, 0, 1f);
mLayout.animateValueForChildAtIndex(DynamicAnimation.SCALE_Y, 0, 1f);
// Fade in the new bubble.
child.setAlpha(0);
mLayout.animateValueForChildAtIndex(DynamicAnimation.ALPHA, 0, 1f);
// Start the new bubble 4x the normal offset distance in the opposite direction. We'll
// animate in from this position. Since the animations are chained, when the new bubble
// flies in from the side, it will push the other ones out of the way.
float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X);
child.setTranslationX(mStackPosition.x - ANIMATE_TRANSLATION_FACTOR * xOffset);
mLayout.animateValueForChildAtIndex(
DynamicAnimation.TRANSLATION_X, 0, mStackPosition.x);
// If this is the first child added, position the stack in its starting position before
// animating in.
moveStackToStartPosition(() -> animateInBubble(child));
} else if (mLayout.indexOfChild(child) == 0) {
// Otherwise, animate the bubble in if it's the newest bubble. If we're adding a bubble
// to the back of the stack, it'll be largely invisible so don't bother animating it in.
animateInBubble(child);
}
}
@@ -334,10 +309,14 @@ public class StackAnimationController extends
}
/** Moves the stack, without any animation, to the starting position. */
private void moveStackToStartPosition() {
mLayout.post(() -> setStackPosition(
getAllowableStackPositionRegion().right,
getAllowableStackPositionRegion().top + mStackStartingVerticalOffset));
private void moveStackToStartPosition(Runnable after) {
// Post to ensure that the layout's width and height have been calculated.
mLayout.post(() -> {
setStackPosition(
getAllowableStackPositionRegion().right,
getAllowableStackPositionRegion().top + mStackStartingVerticalOffset);
after.run();
});
}
/**
@@ -379,6 +358,29 @@ public class StackAnimationController extends
}
}
/** Animates in the given bubble. */
private void animateInBubble(View child) {
child.setTranslationY(mStackPosition.y);
// Pop in the new bubble.
child.setScaleX(ANIMATE_IN_STARTING_SCALE);
child.setScaleY(ANIMATE_IN_STARTING_SCALE);
mLayout.animateValueForChildAtIndex(DynamicAnimation.SCALE_X, 0, 1f);
mLayout.animateValueForChildAtIndex(DynamicAnimation.SCALE_Y, 0, 1f);
// Fade in the new bubble.
child.setAlpha(0);
mLayout.animateValueForChildAtIndex(DynamicAnimation.ALPHA, 0, 1f);
// Start the new bubble 4x the normal offset distance in the opposite direction. We'll
// animate in from this position. Since the animations are chained, when the new bubble
// flies in from the side, it will push the other ones out of the way.
float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X);
child.setTranslationX(mStackPosition.x - ANIMATE_TRANSLATION_FACTOR * xOffset);
mLayout.animateValueForChildAtIndex(
DynamicAnimation.TRANSLATION_X, 0, mStackPosition.x);
}
/**
* Springs the first bubble to the given final position, with the rest of the stack 'following'.
*/