Merge "Restrict the width of bubble expanded view on large screens" into sc-dev

This commit is contained in:
Mady Mellor
2021-04-30 16:07:54 +00:00
committed by Android (Google) Code Review
9 changed files with 166 additions and 126 deletions

View File

@@ -27,24 +27,26 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/bubble_overflow_recycler"
android:layout_gravity="center_horizontal"
android:nestedScrollingEnabled="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:gravity="center"/>
<LinearLayout
android:id="@+id/bubble_overflow_empty_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/bubble_overflow_empty_state_padding"
android:paddingRight="@dimen/bubble_overflow_empty_state_padding"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/bubble_overflow_empty_state_image"
android:layout_width="@dimen/bubble_empty_overflow_image_height"
android:layout_height="@dimen/bubble_empty_overflow_image_height"
android:id="@+id/bubble_overflow_empty_state_image"
android:scaleType="fitCenter"
android:layout_gravity="center"/>
@@ -60,12 +62,12 @@
<TextView
android:id="@+id/bubble_overflow_empty_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"
android:textColor="?android:attr/textColorSecondary"
android:text="@string/bubble_overflow_empty_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/bubble_empty_overflow_subtitle_padding"
android:gravity="center"/>
</LinearLayout>

View File

@@ -32,12 +32,14 @@
android:id="@+id/bubble_view_name"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
android:textSize="13sp"
android:layout_width="fill_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:lines="2"
android:ellipsize="end"
android:layout_gravity="center"
android:paddingTop="@dimen/bubble_overflow_text_padding"
android:paddingEnd="@dimen/bubble_overflow_text_padding"
android:paddingStart="@dimen/bubble_overflow_text_padding"
android:gravity="center"/>
</LinearLayout>

View File

@@ -125,7 +125,9 @@
<dimen name="bubble_expanded_view_slop">8dp</dimen>
<!-- Default (and minimum) height of the expanded view shown when the bubble is expanded -->
<dimen name="bubble_expanded_default_height">180dp</dimen>
<!-- Default height of bubble overflow -->
<!-- On large screens the width of the expanded view is restricted to this size. -->
<dimen name="bubble_expanded_view_tablet_width">412dp</dimen>
<!-- Default (and minimum) height of bubble overflow -->
<dimen name="bubble_overflow_height">480dp</dimen>
<!-- Bubble overflow padding when there are no bubbles -->
<dimen name="bubble_overflow_empty_state_padding">16dp</dimen>

View File

@@ -19,6 +19,7 @@ package com.android.wm.shell.bubbles;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPANDED_VIEW;
@@ -335,7 +336,10 @@ public class BubbleExpandedView extends LinearLayout {
mOverflowView = (BubbleOverflowContainerView) LayoutInflater.from(getContext()).inflate(
R.layout.bubble_overflow_container, null /* root */);
mOverflowView.setBubbleController(mController);
mExpandedViewContainer.addView(mOverflowView);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
mExpandedViewContainer.addView(mOverflowView, lp);
mExpandedViewContainer.setLayoutParams(
new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
bringChildToFront(mOverflowView);
mSettingsIcon.setVisibility(GONE);
} else {
@@ -600,9 +604,9 @@ public class BubbleExpandedView extends LinearLayout {
return;
}
if (mBubble != null || mIsOverflow) {
if ((mBubble != null && mTaskView != null) || mIsOverflow) {
float desiredHeight = mIsOverflow
? mOverflowHeight
? mPositioner.isLargeScreen() ? getMaxExpandedHeight() : mOverflowHeight
: mBubble.getDesiredHeight(mContext);
desiredHeight = Math.max(desiredHeight, mMinHeight);
float height = Math.min(desiredHeight, getMaxExpandedHeight());
@@ -657,10 +661,10 @@ public class BubbleExpandedView extends LinearLayout {
+ getBubbleKey());
}
mExpandedViewContainerLocation = containerLocationOnScreen;
updateHeight();
if (mTaskView != null
&& mTaskView.getVisibility() == VISIBLE
&& mTaskView.isAttachedToWindow()) {
updateHeight();
mTaskView.onLocationChanged();
}
if (mIsOverflow) {

View File

@@ -26,7 +26,6 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -51,8 +50,6 @@ import java.util.function.Consumer;
* Container view for showing aged out bubbles.
*/
public class BubbleOverflowContainerView extends LinearLayout {
static final String EXTRA_BUBBLE_CONTROLLER = "bubble_controller";
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleOverflowActivity" : TAG_BUBBLES;
private LinearLayout mEmptyState;
@@ -64,18 +61,16 @@ public class BubbleOverflowContainerView extends LinearLayout {
private RecyclerView mRecyclerView;
private List<Bubble> mOverflowBubbles = new ArrayList<>();
private class NoScrollGridLayoutManager extends GridLayoutManager {
NoScrollGridLayoutManager(Context context, int columns) {
private class OverflowGridLayoutManager extends GridLayoutManager {
OverflowGridLayoutManager(Context context, int columns) {
super(context, columns);
}
@Override
public boolean canScrollVertically() {
if (getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE) {
return super.canScrollVertically();
}
return false;
}
// @Override
// public boolean canScrollVertically() {
// // TODO (b/162006693): this should be based on items in the list & available height
// return true;
// }
@Override
public int getColumnCountForAccessibility(RecyclerView.Recycler recycler,
@@ -137,47 +132,24 @@ public class BubbleOverflowContainerView extends LinearLayout {
Resources res = getResources();
final int columns = res.getInteger(R.integer.bubbles_overflow_columns);
mRecyclerView.setLayoutManager(
new NoScrollGridLayoutManager(getContext(), columns));
DisplayMetrics displayMetrics = new DisplayMetrics();
getContext().getDisplay().getMetrics(displayMetrics);
final int overflowPadding = res.getDimensionPixelSize(R.dimen.bubble_overflow_padding);
final int recyclerViewWidth = displayMetrics.widthPixels - (overflowPadding * 2);
final int viewWidth = recyclerViewWidth / columns;
final int maxOverflowBubbles = res.getInteger(R.integer.bubbles_max_overflow);
final int rows = (int) Math.ceil((double) maxOverflowBubbles / columns);
final int recyclerViewHeight = res.getDimensionPixelSize(R.dimen.bubble_overflow_height)
- res.getDimensionPixelSize(R.dimen.bubble_overflow_padding);
final int viewHeight = recyclerViewHeight / rows;
new OverflowGridLayoutManager(getContext(), columns));
mAdapter = new BubbleOverflowAdapter(getContext(), mOverflowBubbles,
mController::promoteBubbleFromOverflow,
mController.getPositioner(),
viewWidth, viewHeight);
mController.getPositioner());
mRecyclerView.setAdapter(mAdapter);
mOverflowBubbles.clear();
mOverflowBubbles.addAll(mController.getOverflowBubbles());
mAdapter.notifyDataSetChanged();
// Currently BubbleExpandedView.mExpandedViewContainer is WRAP_CONTENT so use the same
// width we would use for the recycler view
LayoutParams lp = (LayoutParams) mEmptyState.getLayoutParams();
lp.width = recyclerViewWidth;
updateEmptyStateVisibility();
mController.setOverflowListener(mDataListener);
updateEmptyStateVisibility();
updateTheme();
}
void updateEmptyStateVisibility() {
if (mOverflowBubbles.isEmpty()) {
mEmptyState.setVisibility(View.VISIBLE);
} else {
mEmptyState.setVisibility(View.GONE);
}
mEmptyState.setVisibility(mOverflowBubbles.isEmpty() ? View.VISIBLE : View.GONE);
mRecyclerView.setVisibility(mOverflowBubbles.isEmpty() ? View.GONE : View.VISIBLE);
}
/**
@@ -258,20 +230,15 @@ class BubbleOverflowAdapter extends RecyclerView.Adapter<BubbleOverflowAdapter.V
private Consumer<Bubble> mPromoteBubbleFromOverflow;
private BubblePositioner mPositioner;
private List<Bubble> mBubbles;
private int mWidth;
private int mHeight;
BubbleOverflowAdapter(Context context,
List<Bubble> list,
Consumer<Bubble> promoteBubble,
BubblePositioner positioner,
int width, int height) {
BubblePositioner positioner) {
mContext = context;
mBubbles = list;
mPromoteBubbleFromOverflow = promoteBubble;
mPositioner = positioner;
mWidth = width;
mHeight = height;
}
@Override
@@ -284,8 +251,6 @@ class BubbleOverflowAdapter extends RecyclerView.Adapter<BubbleOverflowAdapter.V
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
params.width = mWidth;
params.height = mHeight;
overflowView.setLayoutParams(params);
// Ensure name has enough contrast.

View File

@@ -70,10 +70,16 @@ public class BubblePositioner {
private int mBubbleSize;
private int mBubbleBitmapSize;
private int mExpandedViewLargeScreenWidth;
private int mExpandedViewPadding;
private int mPointerHeight;
private int mBubblePaddingTop;
private PointF mPinLocation;
private PointF mRestingStackPosition;
private int[] mLeftRightPadding = new int[2];
private boolean mIsLargeScreen;
private boolean mShowingInTaskbar;
private @TaskbarPosition int mTaskbarPosition = TASKBAR_POSITION_NONE;
private int mTaskbarIconSize;
@@ -99,15 +105,17 @@ public class BubblePositioner {
return;
}
WindowInsets metricInsets = windowMetrics.getWindowInsets();
Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
| WindowInsets.Type.statusBars()
| WindowInsets.Type.displayCutout());
mIsLargeScreen = mContext.getResources().getConfiguration().smallestScreenWidthDp >= 600;
if (BubbleDebugConfig.DEBUG_POSITIONER) {
Log.w(TAG, "update positioner:"
+ " rotation= " + mRotation
+ " rotation: " + mRotation
+ " insets: " + insets
+ " isLargeScreen: " + mIsLargeScreen
+ " bounds: " + windowMetrics.getBounds()
+ " showingInTaskbar: " + mShowingInTaskbar);
}
@@ -143,6 +151,11 @@ public class BubblePositioner {
Resources res = mContext.getResources();
mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
mBubbleBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_bitmap_size);
mExpandedViewLargeScreenWidth = res.getDimensionPixelSize(
R.dimen.bubble_expanded_view_tablet_width);
mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
if (mShowingInTaskbar) {
adjustForTaskbar();
}
@@ -189,13 +202,16 @@ public class BubblePositioner {
return mInsets;
}
/**
* @return whether the device is in landscape orientation.
*/
/** @return whether the device is in landscape orientation. */
public boolean isLandscape() {
return mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270;
}
/** @return whether the screen is considered large. */
public boolean isLargeScreen() {
return mIsLargeScreen;
}
/**
* Indicates how bubbles appear when expanded.
*
@@ -204,7 +220,7 @@ public class BubblePositioner {
* to the left or right side.
*/
public boolean showBubblesVertically() {
return isLandscape() || mShowingInTaskbar;
return isLandscape() || mShowingInTaskbar || mIsLargeScreen;
}
/** Size of the bubble account for badge & dot. */
@@ -223,6 +239,45 @@ public class BubblePositioner {
return (int) size;
}
/**
* Calculates the left & right padding for the bubble expanded view.
*
* On larger screens the width of the expanded view is restricted via this padding.
* On landscape the bubble overflow expanded view is also restricted via this padding.
*/
public int[] getExpandedViewPadding(boolean onLeft, boolean isOverflow) {
int leftPadding = mInsets.left + mExpandedViewPadding;
int rightPadding = mInsets.right + mExpandedViewPadding;
final boolean isLargeOrOverflow = mIsLargeScreen || isOverflow;
if (showBubblesVertically()) {
if (!onLeft) {
rightPadding += mPointerHeight + mBubbleSize;
leftPadding += isLargeOrOverflow
? (mPositionRect.width() - rightPadding - mExpandedViewLargeScreenWidth)
: 0;
} else {
//TODO: pointer height should be padding between pointer & bubbles here & above
leftPadding += mPointerHeight + mBubbleSize;
rightPadding += isLargeOrOverflow
? (mPositionRect.width() - leftPadding - mExpandedViewLargeScreenWidth)
: 0;
}
}
mLeftRightPadding[0] = leftPadding;
mLeftRightPadding[1] = rightPadding;
return mLeftRightPadding;
}
/** Calculates the y position of the expanded view when it is expanded. */
public float getExpandedViewY() {
final int top = getAvailableRect().top;
if (showBubblesVertically()) {
return top + mExpandedViewPadding;
} else {
return top + mBubbleSize + mBubblePaddingTop;
}
}
/**
* 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.

View File

@@ -35,7 +35,6 @@ import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PointF;
@@ -246,7 +245,6 @@ public class BubbleStackView extends FrameLayout
private int mMaxBubbles;
private int mBubbleSize;
private int mBubbleElevation;
private int mBubblePaddingTop;
private int mBubbleTouchPadding;
private int mExpandedViewPadding;
private int mPointerHeight;
@@ -768,7 +766,6 @@ public class BubbleStackView extends FrameLayout
mMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered);
mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
mBubbleElevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
mBubbleTouchPadding = res.getDimensionPixelSize(R.dimen.bubble_touch_padding);
mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
@@ -905,7 +902,7 @@ public class BubbleStackView extends FrameLayout
afterExpandedViewAnimation();
} /* after */);
mExpandedViewContainer.setTranslationX(0f);
mExpandedViewContainer.setTranslationY(getExpandedViewY());
mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY());
mExpandedViewContainer.setAlpha(1f);
}
removeOnLayoutChangeListener(mOrientationChangedListener);
@@ -1247,9 +1244,6 @@ public class BubbleStackView extends FrameLayout
/** Respond to the display size change by recalculating view size and location. */
public void onDisplaySizeChanged() {
updateOverflow();
Resources res = getContext().getResources();
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
mBubbleSize = mPositioner.getBubbleSize();
for (Bubble b : mBubbleData.getBubbles()) {
if (b.getIconView() == null) {
@@ -1267,6 +1261,9 @@ public class BubbleStackView extends FrameLayout
new RelativeStackPosition(
mPositioner.getRestingPosition(),
mStackAnimationController.getAllowableStackPositionRegion()));
if (mIsExpanded) {
updateExpandedView();
}
}
@Override
@@ -1816,7 +1813,7 @@ public class BubbleStackView extends FrameLayout
}
mExpandedViewContainer.setTranslationX(0f);
mExpandedViewContainer.setTranslationY(getExpandedViewY());
mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY());
mExpandedViewContainer.setAlpha(1f);
int index;
@@ -1865,7 +1862,7 @@ public class BubbleStackView extends FrameLayout
1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT,
1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT,
bubbleWillBeAt + mBubbleSize / 2f,
getExpandedViewY());
mPositioner.getExpandedViewY());
}
mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
@@ -1969,7 +1966,7 @@ public class BubbleStackView extends FrameLayout
mExpandedViewContainerMatrix.setScale(
1f, 1f,
expandingFromBubbleAt + mBubbleSize / 2f,
getExpandedViewY());
mPositioner.getExpandedViewY());
}
mExpandedViewAlphaAnimator.reverse();
@@ -2075,7 +2072,7 @@ public class BubbleStackView extends FrameLayout
1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT,
1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT,
expandingFromBubbleDestination + mBubbleSize / 2f,
getExpandedViewY());
mPositioner.getExpandedViewY());
}
mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
@@ -2313,18 +2310,6 @@ public class BubbleStackView extends FrameLayout
: 0f);
}
/**
* Calculates the y position of the expanded view when it is expanded.
*/
float getExpandedViewY() {
final int top = mPositioner.getAvailableRect().top;
if (mPositioner.showBubblesVertically()) {
return top + mExpandedViewPadding;
} else {
return top + mBubbleSize + mBubblePaddingTop;
}
}
private boolean shouldShowFlyout(Bubble bubble) {
Bubble.FlyoutMessage flyoutMessage = bubble.getFlyoutMessage();
final BadgedImageView bubbleView = bubble.getIconView();
@@ -2697,24 +2682,16 @@ public class BubbleStackView extends FrameLayout
if (DEBUG_BUBBLE_STACK_VIEW) {
Log.d(TAG, "updateExpandedView: mIsExpanded=" + mIsExpanded);
}
// Need to update the padding around the view for any insets
Insets insets = mPositioner.getInsets();
int leftPadding = insets.left + mExpandedViewPadding;
int rightPadding = insets.right + mExpandedViewPadding;
if (mPositioner.showBubblesVertically()) {
if (!mStackAnimationController.isStackOnLeftSide()) {
rightPadding += mPointerHeight + mBubbleSize;
} else {
leftPadding += mPointerHeight + mBubbleSize;
}
}
mExpandedViewContainer.setPadding(leftPadding, 0, rightPadding, 0);
boolean isOverflowExpanded = mExpandedBubble != null
&& mBubbleOverflow.KEY.equals(mExpandedBubble.getKey());
int[] paddings = mPositioner.getExpandedViewPadding(
mStackAnimationController.isStackOnLeftSide(), isOverflowExpanded);
mExpandedViewContainer.setPadding(paddings[0], 0, paddings[1], 0);
if (mIsExpansionAnimating) {
mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
}
if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
mExpandedViewContainer.setTranslationY(getExpandedViewY());
mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY());
mExpandedViewContainer.setTranslationX(0f);
mExpandedBubble.getExpandedView().updateView(
mExpandedViewContainer.getLocationOnScreen());
@@ -2755,13 +2732,14 @@ public class BubbleStackView extends FrameLayout
return;
}
float bubblePosition = mExpandedAnimationController.getBubbleXOrYForOrientation(index);
float expandedViewY = mPositioner.getExpandedViewY();
if (mPositioner.showBubblesVertically()) {
float x = mStackOnLeftOrWillBe
? mPositioner.getAvailableRect().left
: mPositioner.getAvailableRect().right
- mExpandedViewContainer.getPaddingRight()
- mPointerHeight;
float bubbleCenter = bubblePosition - getExpandedViewY() + (mBubbleSize / 2f);
float bubbleCenter = bubblePosition - expandedViewY + (mBubbleSize / 2f);
mExpandedBubble.getExpandedView().setPointerPosition(
x,
bubbleCenter,
@@ -2771,7 +2749,7 @@ public class BubbleStackView extends FrameLayout
float bubbleCenter = bubblePosition + (mBubbleSize / 2f);
mExpandedBubble.getExpandedView().setPointerPosition(
bubbleCenter,
getExpandedViewY(),
expandedViewY,
false,
mStackOnLeftOrWillBe);
}

View File

@@ -16,7 +16,6 @@
package com.android.wm.shell.bubbles.animation;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Path;
import android.graphics.PointF;
@@ -142,6 +141,7 @@ public class ExpandedAnimationController
updateResources();
mExpandedViewPadding = expandedViewPadding;
mOnBubbleAnimatedOutAction = onBubbleAnimatedOutAction;
mCollapsePoint = mPositioner.getDefaultStartPosition();
}
/**
@@ -528,17 +528,34 @@ public class ExpandedAnimationController
startOrUpdatePathAnimation(true /* expanding */);
} else if (mAnimatingCollapse) {
startOrUpdatePathAnimation(false /* expanding */);
} else if (mPositioner.showBubblesVertically()) {
child.setTranslationY(getBubbleXOrYForOrientation(index));
if (!mPreparingToCollapse) {
// Only animate if we're not collapsing as that animation will handle placing the
// new bubble in the stacked position.
Rect availableRect = mPositioner.getAvailableRect();
boolean onLeft = mCollapsePoint != null
&& mCollapsePoint.x < (availableRect.width() / 2f);
float fromX = onLeft
? -mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR
: availableRect.right + mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR;
float toX = onLeft
? availableRect.left + mExpandedViewPadding
: availableRect.right - mBubbleSizePx - mExpandedViewPadding;
animationForChild(child)
.translationX(fromX, toX)
.start();
updateBubblePositions();
}
} else {
child.setTranslationX(getBubbleXOrYForOrientation(index));
// If we're preparing to collapse, don't start animations since the collapse animation
// will take over and animate the new bubble into the correct (stacked) position.
if (!mPreparingToCollapse) {
// Only animate if we're not collapsing as that animation will handle placing the
// new bubble in the stacked position.
float toY = getExpandedY();
float fromY = getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR;
animationForChild(child)
.translationY(
getExpandedY()
- mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR, /* from */
getExpandedY() /* to */)
.translationY(fromY, toY)
.start();
updateBubblePositions();
}
@@ -617,15 +634,16 @@ public class ExpandedAnimationController
}
}
// TODO - could move to method on bubblePositioner if mSpaceBetweenBubbles gets moved
/**
* When bubbles are expanded in portrait, they display at the top of the screen in a horizontal
* row. When in landscape, they show at the left or right side in a vertical row. This method
* accounts for screen orientation and will return an x or y value for the position of the
* bubble in the row.
* row. When in landscape or on a large screen, they show at the left or right side in a
* vertical row. This method accounts for screen orientation and will return an x or y value
* for the position of the bubble in the row.
*
* @param index Bubble index in row.
* @return the y position of the bubble if {@link Configuration#ORIENTATION_LANDSCAPE} and the
* x position if {@link Configuration#ORIENTATION_PORTRAIT}.
* @return the y position of the bubble if showing vertically and the x position if showing
* horizontally.
*/
public float getBubbleXOrYForOrientation(int index) {
if (mLayout == null) {

View File

@@ -958,17 +958,26 @@ public class StackAnimationController extends
if (!isActiveController()) {
return;
}
v.setTranslationX(mStackPosition.x);
final float yOffset =
getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_Y);
final float endY = mStackPosition.y + yOffset * index;
final float startY = endY + NEW_BUBBLE_START_Y;
v.setTranslationY(startY);
float endY = mStackPosition.y + yOffset * index;
float endX = mStackPosition.x;
if (mPositioner.showBubblesVertically()) {
v.setTranslationY(endY);
final float startX = isStackOnLeftSide()
? endX - NEW_BUBBLE_START_Y
: endX + NEW_BUBBLE_START_Y;
v.setTranslationX(startX);
} else {
v.setTranslationX(mStackPosition.x);
final float startY = endY + NEW_BUBBLE_START_Y;
v.setTranslationY(startY);
}
v.setScaleX(NEW_BUBBLE_START_SCALE);
v.setScaleY(NEW_BUBBLE_START_SCALE);
v.setAlpha(0f);
final ViewPropertyAnimator animator = v.animate()
.translationY(endY)
.scaleX(1f)
.scaleY(1f)
.alpha(1f)
@@ -977,6 +986,11 @@ public class StackAnimationController extends
v.setTag(R.id.reorder_animator_tag, null);
});
v.setTag(R.id.reorder_animator_tag, animator);
if (mPositioner.showBubblesVertically()) {
animator.translationX(endX);
} else {
animator.translationY(endY);
}
}
/**