Loading packages/SystemUI/res/layout/bubble_flyout.xml +34 −9 Original line number Diff line number Diff line Loading @@ -15,17 +15,40 @@ --> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <FrameLayout <LinearLayout android:id="@+id/bubble_flyout_text_container" android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="horizontal" android:clipToPadding="false" android:paddingLeft="@dimen/bubble_flyout_padding_x" android:paddingRight="@dimen/bubble_flyout_padding_x" android:clipChildren="false" android:paddingStart="@dimen/bubble_flyout_padding_x" android:paddingEnd="@dimen/bubble_flyout_padding_x" android:paddingTop="@dimen/bubble_flyout_padding_y" android:paddingBottom="@dimen/bubble_flyout_padding_y" android:translationZ="@dimen/bubble_flyout_elevation"> <ImageView android:id="@+id/bubble_flyout_avatar" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginEnd="@dimen/bubble_flyout_avatar_message_space" android:scaleType="centerInside" android:src="@drawable/ic_create_bubble"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/bubble_flyout_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@*android:string/config_bodyFontFamilyMedium" android:maxLines="1" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/> <TextView android:id="@+id/bubble_flyout_text" android:layout_width="wrap_content" Loading @@ -34,6 +57,8 @@ android:maxLines="2" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/> </FrameLayout> </LinearLayout> </LinearLayout> </merge> No newline at end of file packages/SystemUI/res/values/dimens.xml +4 −2 Original line number Diff line number Diff line Loading @@ -1097,13 +1097,15 @@ <!-- How much the bubble flyout text container is elevated. --> <dimen name="bubble_flyout_elevation">4dp</dimen> <!-- How much padding is around the left and right sides of the flyout text. --> <dimen name="bubble_flyout_padding_x">16dp</dimen> <dimen name="bubble_flyout_padding_x">12dp</dimen> <!-- How much padding is around the top and bottom of the flyout text. --> <dimen name="bubble_flyout_padding_y">8dp</dimen> <dimen name="bubble_flyout_padding_y">10dp</dimen> <!-- Size of the triangle that points from the flyout to the bubble stack. --> <dimen name="bubble_flyout_pointer_size">6dp</dimen> <!-- How much space to leave between the flyout (tip of the arrow) and the bubble stack. --> <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> <!-- Padding between status bar and bubbles when displayed in expanded state --> <dimen name="bubble_padding_top">16dp</dimen> <!-- Size of individual bubbles. --> Loading packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +18 −70 Original line number Diff line number Diff line Loading @@ -32,20 +32,17 @@ import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.res.Resources; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcelable; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.List; import java.util.Objects; /** Loading Loading @@ -85,6 +82,18 @@ class Bubble { /** Whether flyout text should be suppressed, regardless of any other flags or state. */ private boolean mSuppressFlyout; /** * Presentational info about the flyout. */ public static class FlyoutMessage { @Nullable public Drawable senderAvatar; @Nullable public CharSequence senderName; @Nullable public CharSequence message; @Nullable public boolean isGroupChat; } private FlyoutMessage mFlyoutMessage; public static String groupId(NotificationEntry entry) { UserHandle user = entry.getSbn().getUser(); return user.getIdentifier() + "|" + entry.getSbn().getPackageName(); Loading Loading @@ -194,6 +203,7 @@ class Bubble { mShortcutInfo = info.shortcutInfo; mAppName = info.appName; mFlyoutMessage = info.flyoutMessage; mExpandedView.update(this); mIconView.update(this, info.badgedBubbleImage, info.dotColor, info.dotPath); Loading Loading @@ -307,6 +317,10 @@ class Bubble { mSuppressFlyout = suppressFlyout; } FlyoutMessage getFlyoutMessage() { return mFlyoutMessage; } /** * Returns whether the notification for this bubble is a foreground service. It shows that this * is an ongoing bubble. Loading Loading @@ -368,72 +382,6 @@ class Bubble { return intent; } /** * Returns our best guess for the most relevant text summary of the latest update to this * notification, based on its type. Returns null if there should not be an update message. */ CharSequence getUpdateMessage(Context context) { final Notification underlyingNotif = mEntry.getSbn().getNotification(); final Class<? extends Notification.Style> style = underlyingNotif.getNotificationStyle(); try { if (Notification.BigTextStyle.class.equals(style)) { // Return the big text, it is big so probably important. If it's not there use the // normal text. CharSequence bigText = underlyingNotif.extras.getCharSequence(Notification.EXTRA_BIG_TEXT); return !TextUtils.isEmpty(bigText) ? bigText : underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT); } else if (Notification.MessagingStyle.class.equals(style)) { final List<Notification.MessagingStyle.Message> messages = Notification.MessagingStyle.Message.getMessagesFromBundleArray( (Parcelable[]) underlyingNotif.extras.get( Notification.EXTRA_MESSAGES)); final Notification.MessagingStyle.Message latestMessage = Notification.MessagingStyle.findLatestIncomingMessage(messages); if (latestMessage != null) { final CharSequence personName = latestMessage.getSenderPerson() != null ? latestMessage.getSenderPerson().getName() : null; // Prepend the sender name if available since group chats also use messaging // style. if (!TextUtils.isEmpty(personName)) { return context.getResources().getString( R.string.notification_summary_message_format, personName, latestMessage.getText()); } else { return latestMessage.getText(); } } } else if (Notification.InboxStyle.class.equals(style)) { CharSequence[] lines = underlyingNotif.extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES); // Return the last line since it should be the most recent. if (lines != null && lines.length > 0) { return lines[lines.length - 1]; } } else if (Notification.MediaStyle.class.equals(style)) { // Return nothing, media updates aren't typically useful as a text update. return null; } else { // Default to text extra. return underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT); } } catch (ClassCastException | NullPointerException | ArrayIndexOutOfBoundsException e) { // No use crashing, we'll just return null and the caller will assume there's no update // message. e.printStackTrace(); } return null; } private int getDimenForPackageUser(Context context, int resId, String pkg, int userId) { PackageManager pm = context.getPackageManager(); Resources r; Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java +52 −12 Original line number Diff line number Diff line Loading @@ -32,11 +32,13 @@ import android.graphics.Path; import android.graphics.PointF; import android.graphics.RectF; import android.graphics.drawable.ShapeDrawable; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.Nullable; Loading Loading @@ -65,7 +67,9 @@ public class BubbleFlyoutView extends FrameLayout { private final float mCornerRadius; private final ViewGroup mFlyoutTextContainer; private final TextView mFlyoutText; private final ImageView mSenderAvatar; private final TextView mSenderText; private final TextView mMessageText; /** Values related to the 'new' dot which we use to figure out where to collapse the flyout. */ private final float mNewDotRadius; Loading Loading @@ -142,7 +146,9 @@ public class BubbleFlyoutView extends FrameLayout { LayoutInflater.from(context).inflate(R.layout.bubble_flyout, this, true); mFlyoutTextContainer = findViewById(R.id.bubble_flyout_text_container); mFlyoutText = mFlyoutTextContainer.findViewById(R.id.bubble_flyout_text); mSenderText = findViewById(R.id.bubble_flyout_name); mSenderAvatar = findViewById(R.id.bubble_flyout_avatar); mMessageText = mFlyoutTextContainer.findViewById(R.id.bubble_flyout_text); final Resources res = getResources(); mFlyoutPadding = res.getDimensionPixelSize(R.dimen.bubble_flyout_padding_x); Loading Loading @@ -204,9 +210,34 @@ public class BubbleFlyoutView extends FrameLayout { /** Configures the flyout, collapsed into to dot form. */ void setupFlyoutStartingAsDot( CharSequence updateMessage, PointF stackPos, float parentWidth, boolean arrowPointingLeft, int dotColor, @Nullable Runnable onLayoutComplete, @Nullable Runnable onHide, float[] dotCenter, boolean hideDot) { Bubble.FlyoutMessage flyoutMessage, PointF stackPos, float parentWidth, boolean arrowPointingLeft, int dotColor, @Nullable Runnable onLayoutComplete, @Nullable Runnable onHide, float[] dotCenter, boolean hideDot) { if (flyoutMessage.senderAvatar != null && flyoutMessage.isGroupChat) { mSenderAvatar.setVisibility(VISIBLE); mSenderAvatar.setImageDrawable(flyoutMessage.senderAvatar); } else { mSenderAvatar.setVisibility(GONE); mSenderAvatar.setTranslationX(0); mMessageText.setTranslationX(0); mSenderText.setTranslationX(0); } // Name visibility if (!TextUtils.isEmpty(flyoutMessage.senderName)) { mSenderText.setText(flyoutMessage.senderName); mSenderText.setVisibility(VISIBLE); } else { mSenderText.setVisibility(GONE); } mArrowPointingLeft = arrowPointingLeft; mDotColor = dotColor; mOnHide = onHide; Loading @@ -217,15 +248,15 @@ public class BubbleFlyoutView extends FrameLayout { // Set the flyout TextView's max width in terms of percent, and then subtract out the // padding so that the entire flyout view will be the desired width (rather than the // TextView being the desired width + extra padding). mFlyoutText.setMaxWidth( mMessageText.setMaxWidth( (int) (parentWidth * FLYOUT_MAX_WIDTH_PERCENT) - mFlyoutPadding * 2); mFlyoutText.setText(updateMessage); mMessageText.setText(flyoutMessage.message); // Wait for the TextView to lay out so we know its line count. post(() -> { float restingTranslationY; // Multi line flyouts get top-aligned to the bubble. if (mFlyoutText.getLineCount() > 1) { if (mMessageText.getLineCount() > 1) { restingTranslationY = stackPos.y + mBubbleIconTopPadding; } else { // Single line flyouts are vertically centered with respect to the bubble. Loading Loading @@ -289,11 +320,20 @@ public class BubbleFlyoutView extends FrameLayout { mPercentStillFlyout = (1f - mPercentTransitionedToDot); // Move and fade out the text. mFlyoutText.setTranslationX( (mArrowPointingLeft ? -getWidth() : getWidth()) * mPercentTransitionedToDot); mFlyoutText.setAlpha(clampPercentage( final float translationX = mPercentTransitionedToDot * (mArrowPointingLeft ? -getWidth() : getWidth()); final float alpha = clampPercentage( (mPercentStillFlyout - (1f - BubbleStackView.FLYOUT_DRAG_PERCENT_DISMISS)) / BubbleStackView.FLYOUT_DRAG_PERCENT_DISMISS)); / BubbleStackView.FLYOUT_DRAG_PERCENT_DISMISS); mMessageText.setTranslationX(translationX); mMessageText.setAlpha(alpha); mSenderText.setTranslationX(translationX); mSenderText.setAlpha(alpha); mSenderAvatar.setTranslationX(translationX); mSenderAvatar.setAlpha(alpha); // Reduce the elevation towards that of the topmost bubble. setTranslationZ( Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +5 −4 Original line number Diff line number Diff line Loading @@ -1377,9 +1377,10 @@ public class BubbleStackView extends FrameLayout { */ @VisibleForTesting void animateInFlyoutForBubble(Bubble bubble) { final CharSequence updateMessage = bubble.getUpdateMessage(getContext()); Bubble.FlyoutMessage flyoutMessage = bubble.getFlyoutMessage(); final BadgedImageView bubbleView = bubble.getIconView(); if (updateMessage == null if (flyoutMessage == null || flyoutMessage.message == null || !bubble.showFlyout() || isExpanded() || mIsExpansionAnimating Loading Loading @@ -1432,8 +1433,8 @@ public class BubbleStackView extends FrameLayout { }; mFlyout.postDelayed(mAnimateInFlyout, 200); }; mFlyout.setupFlyoutStartingAsDot( updateMessage, mStackAnimationController.getStackPosition(), getWidth(), mFlyout.setupFlyoutStartingAsDot(flyoutMessage, mStackAnimationController.getStackPosition(), getWidth(), mStackAnimationController.isStackOnLeftSide(), bubble.getIconView().getDotColor() /* dotColor */, expandFlyoutAfterDelay /* onLayoutComplete */, Loading Loading
packages/SystemUI/res/layout/bubble_flyout.xml +34 −9 Original line number Diff line number Diff line Loading @@ -15,17 +15,40 @@ --> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <FrameLayout <LinearLayout android:id="@+id/bubble_flyout_text_container" android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="horizontal" android:clipToPadding="false" android:paddingLeft="@dimen/bubble_flyout_padding_x" android:paddingRight="@dimen/bubble_flyout_padding_x" android:clipChildren="false" android:paddingStart="@dimen/bubble_flyout_padding_x" android:paddingEnd="@dimen/bubble_flyout_padding_x" android:paddingTop="@dimen/bubble_flyout_padding_y" android:paddingBottom="@dimen/bubble_flyout_padding_y" android:translationZ="@dimen/bubble_flyout_elevation"> <ImageView android:id="@+id/bubble_flyout_avatar" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginEnd="@dimen/bubble_flyout_avatar_message_space" android:scaleType="centerInside" android:src="@drawable/ic_create_bubble"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/bubble_flyout_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@*android:string/config_bodyFontFamilyMedium" android:maxLines="1" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/> <TextView android:id="@+id/bubble_flyout_text" android:layout_width="wrap_content" Loading @@ -34,6 +57,8 @@ android:maxLines="2" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/> </FrameLayout> </LinearLayout> </LinearLayout> </merge> No newline at end of file
packages/SystemUI/res/values/dimens.xml +4 −2 Original line number Diff line number Diff line Loading @@ -1097,13 +1097,15 @@ <!-- How much the bubble flyout text container is elevated. --> <dimen name="bubble_flyout_elevation">4dp</dimen> <!-- How much padding is around the left and right sides of the flyout text. --> <dimen name="bubble_flyout_padding_x">16dp</dimen> <dimen name="bubble_flyout_padding_x">12dp</dimen> <!-- How much padding is around the top and bottom of the flyout text. --> <dimen name="bubble_flyout_padding_y">8dp</dimen> <dimen name="bubble_flyout_padding_y">10dp</dimen> <!-- Size of the triangle that points from the flyout to the bubble stack. --> <dimen name="bubble_flyout_pointer_size">6dp</dimen> <!-- How much space to leave between the flyout (tip of the arrow) and the bubble stack. --> <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> <!-- Padding between status bar and bubbles when displayed in expanded state --> <dimen name="bubble_padding_top">16dp</dimen> <!-- Size of individual bubbles. --> Loading
packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +18 −70 Original line number Diff line number Diff line Loading @@ -32,20 +32,17 @@ import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.res.Resources; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcelable; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.List; import java.util.Objects; /** Loading Loading @@ -85,6 +82,18 @@ class Bubble { /** Whether flyout text should be suppressed, regardless of any other flags or state. */ private boolean mSuppressFlyout; /** * Presentational info about the flyout. */ public static class FlyoutMessage { @Nullable public Drawable senderAvatar; @Nullable public CharSequence senderName; @Nullable public CharSequence message; @Nullable public boolean isGroupChat; } private FlyoutMessage mFlyoutMessage; public static String groupId(NotificationEntry entry) { UserHandle user = entry.getSbn().getUser(); return user.getIdentifier() + "|" + entry.getSbn().getPackageName(); Loading Loading @@ -194,6 +203,7 @@ class Bubble { mShortcutInfo = info.shortcutInfo; mAppName = info.appName; mFlyoutMessage = info.flyoutMessage; mExpandedView.update(this); mIconView.update(this, info.badgedBubbleImage, info.dotColor, info.dotPath); Loading Loading @@ -307,6 +317,10 @@ class Bubble { mSuppressFlyout = suppressFlyout; } FlyoutMessage getFlyoutMessage() { return mFlyoutMessage; } /** * Returns whether the notification for this bubble is a foreground service. It shows that this * is an ongoing bubble. Loading Loading @@ -368,72 +382,6 @@ class Bubble { return intent; } /** * Returns our best guess for the most relevant text summary of the latest update to this * notification, based on its type. Returns null if there should not be an update message. */ CharSequence getUpdateMessage(Context context) { final Notification underlyingNotif = mEntry.getSbn().getNotification(); final Class<? extends Notification.Style> style = underlyingNotif.getNotificationStyle(); try { if (Notification.BigTextStyle.class.equals(style)) { // Return the big text, it is big so probably important. If it's not there use the // normal text. CharSequence bigText = underlyingNotif.extras.getCharSequence(Notification.EXTRA_BIG_TEXT); return !TextUtils.isEmpty(bigText) ? bigText : underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT); } else if (Notification.MessagingStyle.class.equals(style)) { final List<Notification.MessagingStyle.Message> messages = Notification.MessagingStyle.Message.getMessagesFromBundleArray( (Parcelable[]) underlyingNotif.extras.get( Notification.EXTRA_MESSAGES)); final Notification.MessagingStyle.Message latestMessage = Notification.MessagingStyle.findLatestIncomingMessage(messages); if (latestMessage != null) { final CharSequence personName = latestMessage.getSenderPerson() != null ? latestMessage.getSenderPerson().getName() : null; // Prepend the sender name if available since group chats also use messaging // style. if (!TextUtils.isEmpty(personName)) { return context.getResources().getString( R.string.notification_summary_message_format, personName, latestMessage.getText()); } else { return latestMessage.getText(); } } } else if (Notification.InboxStyle.class.equals(style)) { CharSequence[] lines = underlyingNotif.extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES); // Return the last line since it should be the most recent. if (lines != null && lines.length > 0) { return lines[lines.length - 1]; } } else if (Notification.MediaStyle.class.equals(style)) { // Return nothing, media updates aren't typically useful as a text update. return null; } else { // Default to text extra. return underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT); } } catch (ClassCastException | NullPointerException | ArrayIndexOutOfBoundsException e) { // No use crashing, we'll just return null and the caller will assume there's no update // message. e.printStackTrace(); } return null; } private int getDimenForPackageUser(Context context, int resId, String pkg, int userId) { PackageManager pm = context.getPackageManager(); Resources r; Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java +52 −12 Original line number Diff line number Diff line Loading @@ -32,11 +32,13 @@ import android.graphics.Path; import android.graphics.PointF; import android.graphics.RectF; import android.graphics.drawable.ShapeDrawable; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.Nullable; Loading Loading @@ -65,7 +67,9 @@ public class BubbleFlyoutView extends FrameLayout { private final float mCornerRadius; private final ViewGroup mFlyoutTextContainer; private final TextView mFlyoutText; private final ImageView mSenderAvatar; private final TextView mSenderText; private final TextView mMessageText; /** Values related to the 'new' dot which we use to figure out where to collapse the flyout. */ private final float mNewDotRadius; Loading Loading @@ -142,7 +146,9 @@ public class BubbleFlyoutView extends FrameLayout { LayoutInflater.from(context).inflate(R.layout.bubble_flyout, this, true); mFlyoutTextContainer = findViewById(R.id.bubble_flyout_text_container); mFlyoutText = mFlyoutTextContainer.findViewById(R.id.bubble_flyout_text); mSenderText = findViewById(R.id.bubble_flyout_name); mSenderAvatar = findViewById(R.id.bubble_flyout_avatar); mMessageText = mFlyoutTextContainer.findViewById(R.id.bubble_flyout_text); final Resources res = getResources(); mFlyoutPadding = res.getDimensionPixelSize(R.dimen.bubble_flyout_padding_x); Loading Loading @@ -204,9 +210,34 @@ public class BubbleFlyoutView extends FrameLayout { /** Configures the flyout, collapsed into to dot form. */ void setupFlyoutStartingAsDot( CharSequence updateMessage, PointF stackPos, float parentWidth, boolean arrowPointingLeft, int dotColor, @Nullable Runnable onLayoutComplete, @Nullable Runnable onHide, float[] dotCenter, boolean hideDot) { Bubble.FlyoutMessage flyoutMessage, PointF stackPos, float parentWidth, boolean arrowPointingLeft, int dotColor, @Nullable Runnable onLayoutComplete, @Nullable Runnable onHide, float[] dotCenter, boolean hideDot) { if (flyoutMessage.senderAvatar != null && flyoutMessage.isGroupChat) { mSenderAvatar.setVisibility(VISIBLE); mSenderAvatar.setImageDrawable(flyoutMessage.senderAvatar); } else { mSenderAvatar.setVisibility(GONE); mSenderAvatar.setTranslationX(0); mMessageText.setTranslationX(0); mSenderText.setTranslationX(0); } // Name visibility if (!TextUtils.isEmpty(flyoutMessage.senderName)) { mSenderText.setText(flyoutMessage.senderName); mSenderText.setVisibility(VISIBLE); } else { mSenderText.setVisibility(GONE); } mArrowPointingLeft = arrowPointingLeft; mDotColor = dotColor; mOnHide = onHide; Loading @@ -217,15 +248,15 @@ public class BubbleFlyoutView extends FrameLayout { // Set the flyout TextView's max width in terms of percent, and then subtract out the // padding so that the entire flyout view will be the desired width (rather than the // TextView being the desired width + extra padding). mFlyoutText.setMaxWidth( mMessageText.setMaxWidth( (int) (parentWidth * FLYOUT_MAX_WIDTH_PERCENT) - mFlyoutPadding * 2); mFlyoutText.setText(updateMessage); mMessageText.setText(flyoutMessage.message); // Wait for the TextView to lay out so we know its line count. post(() -> { float restingTranslationY; // Multi line flyouts get top-aligned to the bubble. if (mFlyoutText.getLineCount() > 1) { if (mMessageText.getLineCount() > 1) { restingTranslationY = stackPos.y + mBubbleIconTopPadding; } else { // Single line flyouts are vertically centered with respect to the bubble. Loading Loading @@ -289,11 +320,20 @@ public class BubbleFlyoutView extends FrameLayout { mPercentStillFlyout = (1f - mPercentTransitionedToDot); // Move and fade out the text. mFlyoutText.setTranslationX( (mArrowPointingLeft ? -getWidth() : getWidth()) * mPercentTransitionedToDot); mFlyoutText.setAlpha(clampPercentage( final float translationX = mPercentTransitionedToDot * (mArrowPointingLeft ? -getWidth() : getWidth()); final float alpha = clampPercentage( (mPercentStillFlyout - (1f - BubbleStackView.FLYOUT_DRAG_PERCENT_DISMISS)) / BubbleStackView.FLYOUT_DRAG_PERCENT_DISMISS)); / BubbleStackView.FLYOUT_DRAG_PERCENT_DISMISS); mMessageText.setTranslationX(translationX); mMessageText.setAlpha(alpha); mSenderText.setTranslationX(translationX); mSenderText.setAlpha(alpha); mSenderAvatar.setTranslationX(translationX); mSenderAvatar.setAlpha(alpha); // Reduce the elevation towards that of the topmost bubble. setTranslationZ( Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +5 −4 Original line number Diff line number Diff line Loading @@ -1377,9 +1377,10 @@ public class BubbleStackView extends FrameLayout { */ @VisibleForTesting void animateInFlyoutForBubble(Bubble bubble) { final CharSequence updateMessage = bubble.getUpdateMessage(getContext()); Bubble.FlyoutMessage flyoutMessage = bubble.getFlyoutMessage(); final BadgedImageView bubbleView = bubble.getIconView(); if (updateMessage == null if (flyoutMessage == null || flyoutMessage.message == null || !bubble.showFlyout() || isExpanded() || mIsExpansionAnimating Loading Loading @@ -1432,8 +1433,8 @@ public class BubbleStackView extends FrameLayout { }; mFlyout.postDelayed(mAnimateInFlyout, 200); }; mFlyout.setupFlyoutStartingAsDot( updateMessage, mStackAnimationController.getStackPosition(), getWidth(), mFlyout.setupFlyoutStartingAsDot(flyoutMessage, mStackAnimationController.getStackPosition(), getWidth(), mStackAnimationController.isStackOnLeftSide(), bubble.getIconView().getDotColor() /* dotColor */, expandFlyoutAfterDelay /* onLayoutComplete */, Loading