Merge changes I500c566e,I4b5ffc26 into sc-v2-dev
* changes: Update the flyout width to be smaller on large screens Updates to manage button based on latest mocks
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid
|
||||
android:color="@android:color/system_neutral1_900"
|
||||
android:color="@android:color/system_neutral1_800"
|
||||
/>
|
||||
<corners android:radius="20dp" />
|
||||
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
android:id="@+id/settings_button"
|
||||
android:layout_gravity="start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_height="@dimen/bubble_manage_button_height"
|
||||
android:layout_marginStart="@dimen/bubble_manage_button_margin"
|
||||
android:layout_marginTop="@dimen/bubble_manage_button_margin"
|
||||
android:layout_marginBottom="@dimen/bubble_manage_button_margin"
|
||||
android:focusable="true"
|
||||
android:text="@string/manage_bubbles_text"
|
||||
android:textSize="@*android:dimen/text_size_body_2_material"
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
<dimen name="bubble_flyout_space_from_bubble">8dp</dimen>
|
||||
<!-- How much space to leave between the flyout text and the avatar displayed in the flyout. -->
|
||||
<dimen name="bubble_flyout_avatar_message_space">6dp</dimen>
|
||||
<!-- If the screen percentage is smaller than this, we'll use this value instead. -->
|
||||
<dimen name="bubbles_flyout_min_width_large_screen">200dp</dimen>
|
||||
<!-- Padding between status bar and bubbles when displayed in expanded state -->
|
||||
<dimen name="bubble_padding_top">16dp</dimen>
|
||||
<!-- Space between bubbles when expanded. -->
|
||||
@@ -149,7 +151,11 @@
|
||||
<!-- Extra padding around the dismiss target for bubbles -->
|
||||
<dimen name="bubble_dismiss_slop">16dp</dimen>
|
||||
<!-- Height of button allowing users to adjust settings for bubbles. -->
|
||||
<dimen name="bubble_manage_button_height">56dp</dimen>
|
||||
<dimen name="bubble_manage_button_height">36dp</dimen>
|
||||
<!-- Height of manage button including margins. -->
|
||||
<dimen name="bubble_manage_button_total_height">68dp</dimen>
|
||||
<!-- The margin around the outside of the manage button. -->
|
||||
<dimen name="bubble_manage_button_margin">16dp</dimen>
|
||||
<!-- Height of an item in the bubble manage menu. -->
|
||||
<dimen name="bubble_menu_item_height">60dp</dimen>
|
||||
<!-- Padding applied to the bubble manage menu. -->
|
||||
|
||||
@@ -735,6 +735,10 @@ public class BubbleExpandedView extends LinearLayout {
|
||||
mManageButton.getBoundsOnScreen(rect);
|
||||
}
|
||||
|
||||
public int getManageButtonMargin() {
|
||||
return ((LinearLayout.LayoutParams) mManageButton.getLayoutParams()).getMarginStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up anything related to the task and {@code TaskView}. If this view should be reused
|
||||
* after this method is called, then
|
||||
|
||||
@@ -56,9 +56,6 @@ import com.android.wm.shell.common.TriangleShape;
|
||||
* transform into the 'new' dot, which is used during flyout dismiss animations/gestures.
|
||||
*/
|
||||
public class BubbleFlyoutView extends FrameLayout {
|
||||
/** Max width of the flyout, in terms of percent of the screen width. */
|
||||
private static final float FLYOUT_MAX_WIDTH_PERCENT = .6f;
|
||||
|
||||
/** Translation Y of fade animation. */
|
||||
private static final float FLYOUT_FADE_Y = 40f;
|
||||
|
||||
@@ -68,6 +65,8 @@ public class BubbleFlyoutView extends FrameLayout {
|
||||
// Whether the flyout view should show a pointer to the bubble.
|
||||
private static final boolean SHOW_POINTER = false;
|
||||
|
||||
private BubblePositioner mPositioner;
|
||||
|
||||
private final int mFlyoutPadding;
|
||||
private final int mFlyoutSpaceFromBubble;
|
||||
private final int mPointerSize;
|
||||
@@ -156,10 +155,11 @@ public class BubbleFlyoutView extends FrameLayout {
|
||||
/** Callback to run when the flyout is hidden. */
|
||||
@Nullable private Runnable mOnHide;
|
||||
|
||||
public BubbleFlyoutView(Context context) {
|
||||
public BubbleFlyoutView(Context context, BubblePositioner positioner) {
|
||||
super(context);
|
||||
LayoutInflater.from(context).inflate(R.layout.bubble_flyout, this, true);
|
||||
mPositioner = positioner;
|
||||
|
||||
LayoutInflater.from(context).inflate(R.layout.bubble_flyout, this, true);
|
||||
mFlyoutTextContainer = findViewById(R.id.bubble_flyout_text_container);
|
||||
mSenderText = findViewById(R.id.bubble_flyout_name);
|
||||
mSenderAvatar = findViewById(R.id.bubble_flyout_avatar);
|
||||
@@ -230,11 +230,11 @@ public class BubbleFlyoutView extends FrameLayout {
|
||||
/*
|
||||
* Fade animation for consecutive flyouts.
|
||||
*/
|
||||
void animateUpdate(Bubble.FlyoutMessage flyoutMessage, float parentWidth, PointF stackPos,
|
||||
void animateUpdate(Bubble.FlyoutMessage flyoutMessage, PointF stackPos,
|
||||
boolean hideDot, Runnable onHide) {
|
||||
mOnHide = onHide;
|
||||
final Runnable afterFadeOut = () -> {
|
||||
updateFlyoutMessage(flyoutMessage, parentWidth);
|
||||
updateFlyoutMessage(flyoutMessage);
|
||||
// Wait for TextViews to layout with updated height.
|
||||
post(() -> {
|
||||
fade(true /* in */, stackPos, hideDot, () -> {} /* after */);
|
||||
@@ -266,7 +266,7 @@ public class BubbleFlyoutView extends FrameLayout {
|
||||
.withEndAction(afterFade);
|
||||
}
|
||||
|
||||
private void updateFlyoutMessage(Bubble.FlyoutMessage flyoutMessage, float parentWidth) {
|
||||
private void updateFlyoutMessage(Bubble.FlyoutMessage flyoutMessage) {
|
||||
final Drawable senderAvatar = flyoutMessage.senderAvatar;
|
||||
if (senderAvatar != null && flyoutMessage.isGroupChat) {
|
||||
mSenderAvatar.setVisibility(VISIBLE);
|
||||
@@ -278,8 +278,7 @@ public class BubbleFlyoutView extends FrameLayout {
|
||||
mSenderText.setTranslationX(0);
|
||||
}
|
||||
|
||||
final int maxTextViewWidth =
|
||||
(int) (parentWidth * FLYOUT_MAX_WIDTH_PERCENT) - mFlyoutPadding * 2;
|
||||
final int maxTextViewWidth = (int) mPositioner.getMaxFlyoutSize() - mFlyoutPadding * 2;
|
||||
|
||||
// Name visibility
|
||||
if (!TextUtils.isEmpty(flyoutMessage.senderName)) {
|
||||
@@ -328,22 +327,20 @@ public class BubbleFlyoutView extends FrameLayout {
|
||||
void setupFlyoutStartingAsDot(
|
||||
Bubble.FlyoutMessage flyoutMessage,
|
||||
PointF stackPos,
|
||||
float parentWidth,
|
||||
boolean arrowPointingLeft,
|
||||
int dotColor,
|
||||
@Nullable Runnable onLayoutComplete,
|
||||
@Nullable Runnable onHide,
|
||||
float[] dotCenter,
|
||||
boolean hideDot,
|
||||
BubblePositioner positioner) {
|
||||
boolean hideDot) {
|
||||
|
||||
mBubbleSize = positioner.getBubbleSize();
|
||||
mBubbleSize = mPositioner.getBubbleSize();
|
||||
|
||||
mOriginalDotSize = SIZE_PERCENTAGE * mBubbleSize;
|
||||
mNewDotRadius = (DOT_SCALE * mOriginalDotSize) / 2f;
|
||||
mNewDotSize = mNewDotRadius * 2f;
|
||||
|
||||
updateFlyoutMessage(flyoutMessage, parentWidth);
|
||||
updateFlyoutMessage(flyoutMessage);
|
||||
|
||||
mArrowPointingLeft = arrowPointingLeft;
|
||||
mDotColor = dotColor;
|
||||
|
||||
@@ -61,10 +61,16 @@ public class BubblePositioner {
|
||||
public static final int NUM_VISIBLE_WHEN_RESTING = 2;
|
||||
/** Indicates a bubble's height should be the maximum available space. **/
|
||||
public static final int MAX_HEIGHT = -1;
|
||||
/** The max percent of screen width to use for the flyout on large screens. */
|
||||
public static final float FLYOUT_MAX_WIDTH_PERCENT_LARGE_SCREEN = 0.3f;
|
||||
/** The max percent of screen width to use for the flyout on phone. */
|
||||
public static final float FLYOUT_MAX_WIDTH_PERCENT = 0.6f;
|
||||
|
||||
|
||||
private Context mContext;
|
||||
private WindowManager mWindowManager;
|
||||
private Rect mPositionRect;
|
||||
private Rect mScreenRect;
|
||||
private @Surface.Rotation int mRotation = Surface.ROTATION_0;
|
||||
private Insets mInsets;
|
||||
private int mDefaultMaxBubbles;
|
||||
@@ -77,10 +83,10 @@ public class BubblePositioner {
|
||||
private int mPointerMargin;
|
||||
private int mPointerWidth;
|
||||
private int mPointerHeight;
|
||||
private int mPointerOverlap;
|
||||
private int mManageButtonHeight;
|
||||
private int mExpandedViewMinHeight;
|
||||
private int mOverflowHeight;
|
||||
private int mMinimumFlyoutWidthLargeScreen;
|
||||
|
||||
private PointF mPinLocation;
|
||||
private PointF mRestingStackPosition;
|
||||
@@ -149,6 +155,7 @@ public class BubblePositioner {
|
||||
mRotation = rotation;
|
||||
mInsets = insets;
|
||||
|
||||
mScreenRect = new Rect(bounds);
|
||||
mPositionRect = new Rect(bounds);
|
||||
mPositionRect.left += mInsets.left;
|
||||
mPositionRect.top += mInsets.top;
|
||||
@@ -166,10 +173,11 @@ public class BubblePositioner {
|
||||
mPointerWidth = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
|
||||
mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
|
||||
mPointerMargin = res.getDimensionPixelSize(R.dimen.bubble_pointer_margin);
|
||||
mPointerOverlap = res.getDimensionPixelSize(R.dimen.bubble_pointer_overlap);
|
||||
mManageButtonHeight = res.getDimensionPixelSize(R.dimen.bubble_manage_button_height);
|
||||
mManageButtonHeight = res.getDimensionPixelSize(R.dimen.bubble_manage_button_total_height);
|
||||
mExpandedViewMinHeight = res.getDimensionPixelSize(R.dimen.bubble_expanded_default_height);
|
||||
mOverflowHeight = res.getDimensionPixelSize(R.dimen.bubble_overflow_height);
|
||||
mMinimumFlyoutWidthLargeScreen = res.getDimensionPixelSize(
|
||||
R.dimen.bubbles_flyout_min_width_large_screen);
|
||||
|
||||
mMaxBubbles = calculateMaxBubbles();
|
||||
|
||||
@@ -425,6 +433,17 @@ public class BubblePositioner {
|
||||
return rowStart + positionInBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the width of the bubble flyout (message originating from the bubble).
|
||||
*/
|
||||
public float getMaxFlyoutSize() {
|
||||
if (isLargeScreen()) {
|
||||
return Math.max(mScreenRect.width() * FLYOUT_MAX_WIDTH_PERCENT_LARGE_SCREEN,
|
||||
mMinimumFlyoutWidthLargeScreen);
|
||||
}
|
||||
return mScreenRect.width() * FLYOUT_MAX_WIDTH_PERCENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stack's most recent position along the edge of the screen. This is saved when the
|
||||
* last bubble is removed, so that the stack can be restored in its previous position.
|
||||
|
||||
@@ -1186,7 +1186,7 @@ public class BubbleStackView extends FrameLayout
|
||||
if (mFlyout != null) {
|
||||
removeView(mFlyout);
|
||||
}
|
||||
mFlyout = new BubbleFlyoutView(getContext());
|
||||
mFlyout = new BubbleFlyoutView(getContext(), mPositioner);
|
||||
mFlyout.setVisibility(GONE);
|
||||
mFlyout.setOnClickListener(mFlyoutClickListener);
|
||||
mFlyout.setOnTouchListener(mFlyoutTouchListener);
|
||||
@@ -2423,20 +2423,19 @@ public class BubbleStackView extends FrameLayout
|
||||
|
||||
|
||||
if (mFlyout.getVisibility() == View.VISIBLE) {
|
||||
mFlyout.animateUpdate(bubble.getFlyoutMessage(), getWidth(),
|
||||
mFlyout.animateUpdate(bubble.getFlyoutMessage(),
|
||||
mStackAnimationController.getStackPosition(), !bubble.showDot(),
|
||||
mAfterFlyoutHidden /* onHide */);
|
||||
} else {
|
||||
mFlyout.setVisibility(INVISIBLE);
|
||||
mFlyout.setupFlyoutStartingAsDot(bubble.getFlyoutMessage(),
|
||||
mStackAnimationController.getStackPosition(), getWidth(),
|
||||
mStackAnimationController.getStackPosition(),
|
||||
mStackAnimationController.isStackOnLeftSide(),
|
||||
bubble.getIconView().getDotColor() /* dotColor */,
|
||||
expandFlyoutAfterDelay /* onLayoutComplete */,
|
||||
mAfterFlyoutHidden /* onHide */,
|
||||
bubble.getIconView().getDotCenter(),
|
||||
!bubble.showDot(),
|
||||
mPositioner);
|
||||
!bubble.showDot());
|
||||
}
|
||||
mFlyout.bringToFront();
|
||||
});
|
||||
@@ -2548,7 +2547,6 @@ public class BubbleStackView extends FrameLayout
|
||||
R.string.bubbles_app_settings, bubble.getAppName()));
|
||||
}
|
||||
|
||||
mExpandedBubble.getExpandedView().getManageButtonBoundsOnScreen(mTempRect);
|
||||
if (mExpandedBubble.getExpandedView().getTaskView() != null) {
|
||||
mExpandedBubble.getExpandedView().getTaskView().setObscuredTouchRect(mShowingManage
|
||||
? new Rect(0, 0, getWidth(), getHeight())
|
||||
@@ -2560,7 +2558,11 @@ public class BubbleStackView extends FrameLayout
|
||||
|
||||
// When the menu is open, it should be at these coordinates. The menu pops out to the right
|
||||
// in LTR and to the left in RTL.
|
||||
final float targetX = isLtr ? mTempRect.left : mTempRect.right - mManageMenu.getWidth();
|
||||
mExpandedBubble.getExpandedView().getManageButtonBoundsOnScreen(mTempRect);
|
||||
final float margin = mExpandedBubble.getExpandedView().getManageButtonMargin();
|
||||
final float targetX = isLtr
|
||||
? mTempRect.left - margin
|
||||
: mTempRect.right + margin - mManageMenu.getWidth();
|
||||
final float targetY = mTempRect.bottom - mManageMenu.getHeight();
|
||||
|
||||
final float xOffsetForAnimation = (isLtr ? 1 : -1) * mManageMenu.getWidth() / 4f;
|
||||
|
||||
@@ -63,7 +63,7 @@ public class BubbleFlyoutViewTest extends ShellTestCase {
|
||||
mFlyoutMessage.senderName = "Josh";
|
||||
mFlyoutMessage.message = "Hello";
|
||||
|
||||
mFlyout = new BubbleFlyoutView(getContext());
|
||||
mFlyout = new BubbleFlyoutView(getContext(), mPositioner);
|
||||
|
||||
mFlyoutText = mFlyout.findViewById(R.id.bubble_flyout_text);
|
||||
mSenderName = mFlyout.findViewById(R.id.bubble_flyout_name);
|
||||
@@ -75,9 +75,8 @@ public class BubbleFlyoutViewTest extends ShellTestCase {
|
||||
public void testShowFlyout_isVisible() {
|
||||
mFlyout.setupFlyoutStartingAsDot(
|
||||
mFlyoutMessage,
|
||||
new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter,
|
||||
false,
|
||||
mPositioner);
|
||||
new PointF(100, 100), true, Color.WHITE, null, null, mDotCenter,
|
||||
false);
|
||||
mFlyout.setVisibility(View.VISIBLE);
|
||||
|
||||
assertEquals("Hello", mFlyoutText.getText());
|
||||
@@ -89,9 +88,8 @@ public class BubbleFlyoutViewTest extends ShellTestCase {
|
||||
public void testFlyoutHide_runsCallback() {
|
||||
Runnable after = mock(Runnable.class);
|
||||
mFlyout.setupFlyoutStartingAsDot(mFlyoutMessage,
|
||||
new PointF(100, 100), 500, true, Color.WHITE, null, after, mDotCenter,
|
||||
false,
|
||||
mPositioner);
|
||||
new PointF(100, 100), true, Color.WHITE, null, after, mDotCenter,
|
||||
false);
|
||||
mFlyout.hideFlyout();
|
||||
|
||||
verify(after).run();
|
||||
@@ -100,9 +98,8 @@ public class BubbleFlyoutViewTest extends ShellTestCase {
|
||||
@Test
|
||||
public void testSetCollapsePercent() {
|
||||
mFlyout.setupFlyoutStartingAsDot(mFlyoutMessage,
|
||||
new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter,
|
||||
false,
|
||||
mPositioner);
|
||||
new PointF(100, 100), true, Color.WHITE, null, null, mDotCenter,
|
||||
false);
|
||||
mFlyout.setVisibility(View.VISIBLE);
|
||||
|
||||
mFlyout.setCollapsePercent(1f);
|
||||
|
||||
Reference in New Issue
Block a user