diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java index 67e5927961815..4028fda6c1df6 100644 --- a/core/java/com/android/internal/widget/ConversationLayout.java +++ b/core/java/com/android/internal/widget/ConversationLayout.java @@ -16,6 +16,9 @@ package com.android.internal.widget; +import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_EXTERNAL; +import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE; + import android.annotation.AttrRes; import android.annotation.NonNull; import android.annotation.Nullable; @@ -35,6 +38,7 @@ import android.os.Bundle; import android.os.Parcelable; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.Gravity; @@ -46,6 +50,7 @@ import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.RemoteViews; import android.widget.TextView; @@ -109,13 +114,13 @@ public class ConversationLayout extends FrameLayout private View mExpandButtonContainer; private ViewGroup mExpandButtonAndContentContainer; private NotificationExpandButton mExpandButton; + private MessagingLinearLayout mImageMessageContainer; private int mExpandButtonExpandedTopMargin; private int mBadgedSideMargins; private int mIconSizeBadged; private int mIconSizeCentered; private CachingIconView mIcon; private int mExpandedGroupTopMargin; - private int mExpandButtonExpandedSize; private View mConversationFacePile; private int mNotificationBackgroundColor; private CharSequence mFallbackChatName; @@ -126,6 +131,7 @@ public class ConversationLayout extends FrameLayout private View mContentContainer; private boolean mExpandable = true; private int mContentMarginEnd; + private Rect mMessagingClipRect; public ConversationLayout(@NonNull Context context) { super(context); @@ -150,12 +156,13 @@ public class ConversationLayout extends FrameLayout super.onFinishInflate(); mMessagingLinearLayout = findViewById(R.id.notification_messaging); mMessagingLinearLayout.setMessagingLayout(this); + mImageMessageContainer = findViewById(R.id.conversation_image_message_container); // We still want to clip, but only on the top, since views can temporarily out of bounds // during transitions. DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); int size = Math.max(displayMetrics.widthPixels, displayMetrics.heightPixels); - Rect rect = new Rect(0, 0, size, size); - mMessagingLinearLayout.setClipBounds(rect); + mMessagingClipRect = new Rect(0, 0, size, size); + setMessagingClippingDisabled(false); mTitleView = findViewById(R.id.title); mAvatarSize = getResources().getDimensionPixelSize(R.dimen.messaging_avatar_size); mTextPaint.setTextAlign(Paint.Align.CENTER); @@ -176,8 +183,6 @@ public class ConversationLayout extends FrameLayout mExpandButton = findViewById(R.id.expand_button); mExpandButtonExpandedTopMargin = getResources().getDimensionPixelSize( R.dimen.conversation_expand_button_top_margin_expanded); - mExpandButtonExpandedSize = getResources().getDimensionPixelSize( - R.dimen.conversation_expand_button_expanded_size); mNotificationHeaderExpandedPadding = getResources().getDimensionPixelSize( R.dimen.conversation_header_expanded_padding_end); mContentMarginEnd = getResources().getDimensionPixelSize( @@ -370,6 +375,41 @@ public class ConversationLayout extends FrameLayout messagingGroup.setCanHideSenderIfFirst(canHide); } updateIconPositionAndSize(); + updateImageMessages(); + } + + private void updateImageMessages() { + boolean displayExternalImage = false; + ArraySet newMessages = new ArraySet<>(); + if (mIsCollapsed) { + + // When collapsed, we're displaying all image messages in a dedicated container + // on the right of the layout instead of inline. Let's add all isolated images there + int imageIndex = 0; + for (int i = 0; i < mGroups.size(); i++) { + MessagingGroup messagingGroup = mGroups.get(i); + MessagingImageMessage isolatedMessage = messagingGroup.getIsolatedMessage(); + if (isolatedMessage != null) { + newMessages.add(isolatedMessage.getView()); + displayExternalImage = true; + if (imageIndex + != mImageMessageContainer.indexOfChild(isolatedMessage.getView())) { + mImageMessageContainer.removeView(isolatedMessage.getView()); + mImageMessageContainer.addView(isolatedMessage.getView(), imageIndex); + } + imageIndex++; + } + } + } + // Remove all messages that don't belong into the image layout + for (int i = 0; i < mImageMessageContainer.getChildCount(); i++) { + View child = mImageMessageContainer.getChildAt(i); + if (!newMessages.contains(child)) { + mImageMessageContainer.removeView(child); + i--; + } + } + mImageMessageContainer.setVisibility(displayExternalImage ? VISIBLE : GONE); } private void bindFacePile() { @@ -662,7 +702,9 @@ public class ConversationLayout extends FrameLayout newGroup = MessagingGroup.createGroup(mMessagingLinearLayout); mAddedGroups.add(newGroup); } - newGroup.setDisplayImagesAtEnd(mIsCollapsed); + newGroup.setImageDisplayLocation(mIsCollapsed + ? IMAGE_DISPLAY_LOCATION_EXTERNAL + : IMAGE_DISPLAY_LOCATION_INLINE); newGroup.setIsInConversation(true); newGroup.setLayoutColor(mLayoutColor); newGroup.setTextColors(mSenderTextColor, mMessageTextColor); @@ -817,6 +859,10 @@ public class ConversationLayout extends FrameLayout return mMessagingLinearLayout; } + public @NonNull ViewGroup getImageMessageContainer() { + return mImageMessageContainer; + } + public ArrayList getMessagingGroups() { return mGroups; } @@ -827,20 +873,17 @@ public class ConversationLayout extends FrameLayout int gravity; int topMargin = 0; ViewGroup newContainer; - int newContainerHeight; if (mIsCollapsed) { drawableId = R.drawable.ic_expand_notification; contentDescriptionId = R.string.expand_button_content_description_collapsed; gravity = Gravity.CENTER; newContainer = mExpandButtonAndContentContainer; - newContainerHeight = LayoutParams.MATCH_PARENT; } else { drawableId = R.drawable.ic_collapse_notification; contentDescriptionId = R.string.expand_button_content_description_expanded; gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; topMargin = mExpandButtonExpandedTopMargin; newContainer = this; - newContainerHeight = mExpandButtonExpandedSize; } mExpandButton.setImageDrawable(getContext().getDrawable(drawableId)); mExpandButton.setColorFilter(mExpandButton.getOriginalNotificationColor()); @@ -850,14 +893,11 @@ public class ConversationLayout extends FrameLayout if (newContainer != mExpandButtonContainer.getParent()) { ((ViewGroup) mExpandButtonContainer.getParent()).removeView(mExpandButtonContainer); newContainer.addView(mExpandButtonContainer); - MarginLayoutParams layoutParams = - (MarginLayoutParams) mExpandButtonContainer.getLayoutParams(); - layoutParams.height = newContainerHeight; - mExpandButtonContainer.setLayoutParams(layoutParams); } // update if the expand button is centered - FrameLayout.LayoutParams layoutParams = (LayoutParams) mExpandButton.getLayoutParams(); + LinearLayout.LayoutParams layoutParams = + (LinearLayout.LayoutParams) mExpandButton.getLayoutParams(); layoutParams.gravity = gravity; layoutParams.topMargin = topMargin; mExpandButton.setLayoutParams(layoutParams); @@ -905,4 +945,9 @@ public class ConversationLayout extends FrameLayout } updateContentPaddings(); } + + @Override + public void setMessagingClippingDisabled(boolean clippingDisabled) { + mMessagingLinearLayout.setClipBounds(clippingDisabled ? null : mMessagingClipRect); + } } diff --git a/core/java/com/android/internal/widget/IMessagingLayout.java b/core/java/com/android/internal/widget/IMessagingLayout.java index 149d05641a0b8..b72c081f134cb 100644 --- a/core/java/com/android/internal/widget/IMessagingLayout.java +++ b/core/java/com/android/internal/widget/IMessagingLayout.java @@ -39,4 +39,9 @@ public interface IMessagingLayout { * @return the list of messaging groups */ ArrayList getMessagingGroups(); + + /** + * Disable the clipping of the messaging container. + */ + void setMessagingClippingDisabled(boolean clippingDisabled); } diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java index c68da97ab3b41..53272f7eebf95 100644 --- a/core/java/com/android/internal/widget/MessagingGroup.java +++ b/core/java/com/android/internal/widget/MessagingGroup.java @@ -17,6 +17,7 @@ package com.android.internal.widget; import android.annotation.AttrRes; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; @@ -44,6 +45,8 @@ import android.widget.RemoteViews; import com.android.internal.R; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; @@ -54,6 +57,23 @@ import java.util.List; public class MessagingGroup extends LinearLayout implements MessagingLinearLayout.MessagingChild { private static Pools.SimplePool sInstancePool = new Pools.SynchronizedPool<>(10); + + /** + * Images are displayed inline. + */ + public static final int IMAGE_DISPLAY_LOCATION_INLINE = 0; + + /** + * Images are displayed at the end of the group. + */ + public static final int IMAGE_DISPLAY_LOCATION_AT_END = 1; + + /** + * Images are displayed externally. + */ + public static final int IMAGE_DISPLAY_LOCATION_EXTERNAL = 2; + + private MessagingLinearLayout mMessageContainer; ImageFloatingTextView mSenderView; private ImageView mAvatarView; @@ -70,7 +90,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou private boolean mIsHidingAnimated; private boolean mNeedsGeneratedAvatar; private Person mSender; - private boolean mImagesAtEnd; + private @ImageDisplayLocation int mImageDisplayLocation; private ViewGroup mImageContainer; private MessagingImageMessage mIsolatedMessage; private boolean mClippingDisabled; @@ -476,7 +496,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou mAddedMessages.add(message); } boolean isImage = message instanceof MessagingImageMessage; - if (mImagesAtEnd && isImage) { + if (mImageDisplayLocation != IMAGE_DISPLAY_LOCATION_INLINE && isImage) { isolatedMessage = (MessagingImageMessage) message; } else { if (removeFromParentIfDifferent(message, mMessageContainer)) { @@ -500,9 +520,12 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou } } if (isolatedMessage != null) { - if (removeFromParentIfDifferent(isolatedMessage, mImageContainer)) { + if (mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_AT_END + && removeFromParentIfDifferent(isolatedMessage, mImageContainer)) { mImageContainer.removeAllViews(); mImageContainer.addView(isolatedMessage.getView()); + } else if (mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_EXTERNAL) { + mImageContainer.removeAllViews(); } isolatedMessage.setIsolated(true); } else if (mIsolatedMessage != null) { @@ -515,7 +538,8 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou } private void updateImageContainerVisibility() { - mImageContainer.setVisibility(mIsolatedMessage != null && mImagesAtEnd + mImageContainer.setVisibility(mIsolatedMessage != null + && mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_AT_END ? View.VISIBLE : View.GONE); } @@ -620,9 +644,9 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou mClippingDisabled = disabled; } - public void setDisplayImagesAtEnd(boolean atEnd) { - if (mImagesAtEnd != atEnd) { - mImagesAtEnd = atEnd; + public void setImageDisplayLocation(@ImageDisplayLocation int displayLocation) { + if (mImageDisplayLocation != displayLocation) { + mImageDisplayLocation = displayLocation; updateImageContainerVisibility(); } } @@ -670,4 +694,13 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou mMessagingIconContainer.setLayoutParams(layoutParams); } } + + @IntDef(prefix = {"IMAGE_DISPLAY_LOCATION_"}, value = { + IMAGE_DISPLAY_LOCATION_INLINE, + IMAGE_DISPLAY_LOCATION_AT_END, + IMAGE_DISPLAY_LOCATION_EXTERNAL + }) + @Retention(RetentionPolicy.SOURCE) + private @interface ImageDisplayLocation { + } } diff --git a/core/java/com/android/internal/widget/MessagingImageMessage.java b/core/java/com/android/internal/widget/MessagingImageMessage.java index c243f3b583e5f..27689d4d43f95 100644 --- a/core/java/com/android/internal/widget/MessagingImageMessage.java +++ b/core/java/com/android/internal/widget/MessagingImageMessage.java @@ -149,10 +149,16 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage protected void onDraw(Canvas canvas) { canvas.save(); canvas.clipPath(getRoundedRectPath()); - int width = (int) Math.max(getActualWidth(), getActualHeight() * mAspectRatio); - int height = (int) (width / mAspectRatio); + // Calculate the right sizing ensuring that the image is nicely centered in the layout + // during transitions + int width = (int) Math.max((Math.min(getHeight(), getActualHeight()) * mAspectRatio), + getActualWidth()); + int height = (int) Math.max((Math.min(getWidth(), getActualWidth()) / mAspectRatio), + getActualHeight()); + height = (int) Math.max(height, width / mAspectRatio); int left = (int) ((getActualWidth() - width) / 2.0f); - mDrawable.setBounds(left, 0, left + width, height); + int top = (int) ((getActualHeight() - height) / 2.0f); + mDrawable.setBounds(left, top, left + width, top + height); mDrawable.draw(canvas); canvas.restore(); } @@ -222,8 +228,17 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mIsIsolated) { + // When isolated we have a fixed size, let's use that sizing. setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); + } else { + // If we are displaying inline, we never want to go wider than actual size of the + // image, otherwise it will look quite blurry. + int width = Math.min(MeasureSpec.getSize(widthMeasureSpec), + mDrawable.getIntrinsicWidth()); + int height = (int) Math.min(MeasureSpec.getSize(heightMeasureSpec), width + / mAspectRatio); + setMeasuredDimension(width, height); } } @@ -231,7 +246,7 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // TODO: ensure that this isn't called when transforming - setActualWidth(getStaticWidth()); + setActualWidth(getWidth()); setActualHeight(getHeight()); } @@ -258,13 +273,6 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage return mActualHeight; } - public int getStaticWidth() { - if (mIsIsolated) { - return getWidth(); - } - return (int) (getHeight() * mAspectRatio); - } - public void setIsolated(boolean isolated) { if (mIsIsolated != isolated) { mIsIsolated = isolated; diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java index 3fb5d43bea5a2..a162e4e10c71f 100644 --- a/core/java/com/android/internal/widget/MessagingLayout.java +++ b/core/java/com/android/internal/widget/MessagingLayout.java @@ -16,6 +16,9 @@ package com.android.internal.widget; +import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_AT_END; +import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE; + import android.annotation.AttrRes; import android.annotation.NonNull; import android.annotation.Nullable; @@ -447,7 +450,9 @@ public class MessagingLayout extends FrameLayout newGroup = MessagingGroup.createGroup(mMessagingLinearLayout); mAddedGroups.add(newGroup); } - newGroup.setDisplayImagesAtEnd(mDisplayImagesAtEnd); + newGroup.setImageDisplayLocation(mDisplayImagesAtEnd + ? IMAGE_DISPLAY_LOCATION_AT_END + : IMAGE_DISPLAY_LOCATION_INLINE); newGroup.setIsInConversation(false); newGroup.setLayoutColor(mLayoutColor); newGroup.setTextColors(mSenderTextColor, mMessageTextColor); @@ -599,4 +604,9 @@ public class MessagingLayout extends FrameLayout public ArrayList getMessagingGroups() { return mGroups; } + + @Override + public void setMessagingClippingDisabled(boolean clippingDisabled) { + // Don't do anything, this is only used for the ConversationLayout + } } diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml index 2348deeed7fb3..82465831aa690 100644 --- a/core/res/res/layout/notification_template_material_conversation.xml +++ b/core/res/res/layout/notification_template_material_conversation.xml @@ -31,6 +31,7 @@ android:clipChildren="false" android:clipToPadding="false" android:paddingTop="12dp" + android:paddingBottom="12dp" > - + android:orientation="horizontal" + android:paddingEnd="@dimen/notification_content_margin_end" + android:clipToPadding="false" + android:clipChildren="false" + > + + - + diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 4c79acaf48549..2efb2ec207072 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -688,8 +688,8 @@ 52dp 80dp - - 80dp + + 80dp 18dp diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e7b9ada8ade77..af697ebe78873 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3871,8 +3871,8 @@ + - diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java index a3fb2251f5aa2..2ee21539ca1d8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java @@ -82,7 +82,7 @@ public class MessagingImageTransformState extends ImageTransformState { float startActualWidth = getStartActualWidth(); mImageMessage.setActualWidth( (int) NotificationUtils.interpolate(startActualWidth, - mImageMessage.getStaticWidth(), + mImageMessage.getWidth(), interpolatedValue)); float startActualHeight = getStartActualHeight(); mImageMessage.setActualHeight( @@ -121,7 +121,7 @@ public class MessagingImageTransformState extends ImageTransformState { @Override protected void resetTransformedView() { super.resetTransformedView(); - mImageMessage.setActualWidth(mImageMessage.getStaticWidth()); + mImageMessage.setActualWidth(mImageMessage.getWidth()); mImageMessage.setActualHeight(mImageMessage.getHeight()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java index 9383f537db455..ccf5a0bb59324 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java @@ -245,6 +245,7 @@ public class MessagingLayoutTransformState extends TransformState { if (isGone(child)) { continue; } + float messageAmount = transformationAmount; int otherIndex = otherMessages.size() - 1 - i; View otherChild = null; if (otherIndex >= 0) { @@ -257,18 +258,19 @@ public class MessagingLayoutTransformState extends TransformState { // Let's fade out as we approach the top of the screen. We can only do this if // we're actually moving up float distanceToTop = child.getTop() + child.getHeight() + previousTranslation; - transformationAmount = distanceToTop / child.getHeight(); - transformationAmount = Math.max(0.0f, Math.min(1.0f, transformationAmount)); + messageAmount = distanceToTop / child.getHeight(); + messageAmount = Math.max(0.0f, Math.min(1.0f, messageAmount)); if (to) { - transformationAmount = 1.0f - transformationAmount; + messageAmount = 1.0f - messageAmount; } } - transformView(transformationAmount, to, child, otherChild, false, /* sameAsAny */ + transformView(messageAmount, to, child, otherChild, false, /* sameAsAny */ useLinearTransformation); boolean otherIsIsolated = otherGroup.getIsolatedMessage() == otherChild; - if (transformationAmount == 0.0f + if (messageAmount == 0.0f && (otherIsIsolated || otherGroup.isSingleLine())) { ownGroup.setClippingDisabled(true); + mMessagingLayout.setMessagingClippingDisabled(true); } if (otherChild == null) { child.setTranslationY(previousTranslation); @@ -362,6 +364,9 @@ public class MessagingLayoutTransformState extends TransformState { if (view.getVisibility() == View.GONE) { return true; } + if (view.getParent() == null) { + return true; + } final ViewGroup.LayoutParams lp = view.getLayoutParams(); if (lp instanceof MessagingLinearLayout.LayoutParams && ((MessagingLinearLayout.LayoutParams) lp).hide) { @@ -433,6 +438,7 @@ public class MessagingLayoutTransformState extends TransformState { ownGroup.setClippingDisabled(false); ownGroup.updateClipRect(); } + mMessagingLayout.setMessagingClippingDisabled(false); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java index 337f312953082..82fb49144181e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java @@ -100,7 +100,7 @@ public class TransformState { transformViewFullyFrom(otherState, transformationAmount); } - protected void ensureVisible() { + public void ensureVisible() { if (mTransformedView.getVisibility() == View.INVISIBLE || mTransformedView.getAlpha() != 1.0f) { // We have the same content, lets show ourselves diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt index 162786cc1fbdd..8b6081ea547cd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt @@ -18,12 +18,16 @@ package com.android.systemui.statusbar.notification.row.wrapper import android.content.Context import android.view.View - +import android.view.ViewGroup import com.android.internal.widget.ConversationLayout import com.android.internal.widget.MessagingLinearLayout import com.android.systemui.R +import com.android.systemui.statusbar.TransformableView +import com.android.systemui.statusbar.ViewTransformationHelper import com.android.systemui.statusbar.notification.NotificationUtils +import com.android.systemui.statusbar.notification.TransformState import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.notification.row.HybridNotificationView /** * Wraps a notification containing a converation template @@ -41,6 +45,7 @@ class NotificationConversationTemplateViewWrapper constructor( private var conversationBadge: View? = null private var expandButton: View? = null private lateinit var expandButtonContainer: View + private lateinit var imageMessageContainer: ViewGroup private var messagingLinearLayout: MessagingLinearLayout? = null init { @@ -51,6 +56,7 @@ class NotificationConversationTemplateViewWrapper constructor( private fun resolveViews() { messagingLinearLayout = conversationLayout.messagingLinearLayout + imageMessageContainer = conversationLayout.imageMessageContainer conversationIcon = conversationLayout.requireViewById( com.android.internal.R.id.conversation_icon) conversationBadge = conversationLayout.requireViewById( @@ -74,6 +80,36 @@ class NotificationConversationTemplateViewWrapper constructor( messagingLinearLayout?.let { mTransformationHelper.addTransformedView(it.id, it) } + + // Let's ignore the image message container since that is transforming as part of the + // messages already + mTransformationHelper.setCustomTransformation( + object : ViewTransformationHelper.CustomTransformation() { + override fun transformTo(ownState: TransformState, + otherView: TransformableView, + transformationAmount: Float): Boolean { + if (otherView is HybridNotificationView) { + return false + } + // we're hidden by default by the transformState + ownState.ensureVisible(); + // Let's do nothing otherwise, this is already handled by the messages + return true + } + + override fun transformFrom(ownState: TransformState, + otherView: TransformableView, + transformationAmount: Float): Boolean { + if (otherView is HybridNotificationView) { + return false + } + // we're hidden by default by the transformState + ownState.ensureVisible(); + // Let's do nothing otherwise, this is already handled by the messages + return true + } + }, imageMessageContainer.id) + conversationIcon?.let { mTransformationHelper.addViewTransformingToSimilar(it.id, it) }