From cef53f36debad86406abb6a0bf87a1515a98923e Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Thu, 19 Mar 2020 19:31:25 -0700 Subject: [PATCH] Improved the transitions and layout of the app name in conversations The transition was using getTop instead of absolute positions which didn't work well for the conversation layout. Also, we were fading in views that were GONE and making them VISIBLE which lead to bugs during the transitions. Additionally, the header text would become visible when a notification was removed from a group and reset. Bug: 150905003 Test: visual, add conversations in groups and non-groups Change-Id: I3c31006a1fc79f7d58cc1dd3d5af44129c9f02bb --- .../internal/widget/ConversationLayout.java | 4 ++ ...ication_template_material_conversation.xml | 4 +- core/res/res/values/dimens.xml | 4 +- .../systemui/statusbar/CrossFadeHelper.java | 6 ++- .../statusbar/NotificationHeaderUtil.java | 40 ++++++++++++++----- .../MessagingLayoutTransformState.java | 16 +++++--- 6 files changed, 52 insertions(+), 22 deletions(-) diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java index 49cf3e099c55b..4e7ae8a235e78 100644 --- a/core/java/com/android/internal/widget/ConversationLayout.java +++ b/core/java/com/android/internal/widget/ConversationLayout.java @@ -469,6 +469,10 @@ public class ConversationLayout extends FrameLayout mAppName.setVisibility(mIsCollapsed ? GONE : VISIBLE); } + public boolean shouldHideAppName() { + return mIsCollapsed; + } + /** * update the icon position and sizing */ diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml index 0c4be1a91a04f..0f895d68893fa 100644 --- a/core/res/res/layout/notification_template_material_conversation.xml +++ b/core/res/res/layout/notification_template_material_conversation.xml @@ -122,6 +122,7 @@ android:layout_height="wrap_content" android:orientation="horizontal" android:paddingTop="16dp" + android:layout_marginBottom="2dp" android:paddingStart="@dimen/conversation_content_start" > @@ -190,7 +191,6 @@ android:id="@+id/notification_messaging" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="2dp" android:spacing="@dimen/notification_messaging_spacing" android:clipToPadding="false" android:clipChildren="false" diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index abc969271c533..f2e25998e0aec 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -695,9 +695,9 @@ 20dp - 25dp + 26dp - 5dp + 12dp 38dp diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java index 164215befe796..b57b22fed8536 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java @@ -50,7 +50,9 @@ public class CrossFadeHelper { if (endRunnable != null) { endRunnable.run(); } - view.setVisibility(View.INVISIBLE); + if (view.getVisibility() != View.GONE) { + view.setVisibility(View.INVISIBLE); + } } }); if (view.hasOverlappingRendering()) { @@ -75,7 +77,7 @@ public class CrossFadeHelper { */ public static void fadeOut(View view, float fadeOutAmount, boolean remap) { view.animate().cancel(); - if (fadeOutAmount == 1.0f) { + if (fadeOutAmount == 1.0f && view.getVisibility() != View.GONE) { view.setVisibility(View.INVISIBLE); } else if (view.getVisibility() == View.INVISIBLE) { view.setVisibility(View.VISIBLE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java index 4759d56099f3c..ba3db09374221 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java @@ -28,6 +28,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.internal.util.ContrastColorUtil; +import com.android.internal.widget.ConversationLayout; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationContentView; @@ -42,6 +43,7 @@ public class NotificationHeaderUtil { private static final TextViewComparator sTextViewComparator = new TextViewComparator(); private static final VisibilityApplicator sVisibilityApplicator = new VisibilityApplicator(); + private static final VisibilityApplicator sAppNameApplicator = new AppNameApplicator(); private static final DataExtractor sIconExtractor = new DataExtractor() { @Override public Object extractData(ExpandableNotificationRow row) { @@ -64,7 +66,7 @@ public class NotificationHeaderUtil { }; private final static ResultApplicator mGreyApplicator = new ResultApplicator() { @Override - public void apply(View view, boolean apply) { + public void apply(View parent, View view, boolean apply, boolean reset) { NotificationHeaderView header = (NotificationHeaderView) view; ImageView icon = (ImageView) view.findViewById( com.android.internal.R.id.icon); @@ -132,8 +134,12 @@ public class NotificationHeaderUtil { } }, sVisibilityApplicator)); - mComparators.add(HeaderProcessor.forTextView(mRow, - com.android.internal.R.id.app_name_text)); + mComparators.add(new HeaderProcessor( + mRow, + com.android.internal.R.id.app_name_text, + null, + sTextViewComparator, + sAppNameApplicator)); mComparators.add(HeaderProcessor.forTextView(mRow, com.android.internal.R.id.header_text)); mDividers.add(com.android.internal.R.id.header_text_divider); @@ -299,19 +305,19 @@ public class NotificationHeaderUtil { public void apply(ExpandableNotificationRow row, boolean reset) { boolean apply = mApply && !reset; if (row.isSummaryWithChildren()) { - applyToView(apply, row.getNotificationHeader()); + applyToView(apply, reset, row.getNotificationHeader()); return; } - applyToView(apply, row.getPrivateLayout().getContractedChild()); - applyToView(apply, row.getPrivateLayout().getHeadsUpChild()); - applyToView(apply, row.getPrivateLayout().getExpandedChild()); + applyToView(apply, reset, row.getPrivateLayout().getContractedChild()); + applyToView(apply, reset, row.getPrivateLayout().getHeadsUpChild()); + applyToView(apply, reset, row.getPrivateLayout().getExpandedChild()); } - private void applyToView(boolean apply, View parent) { + private void applyToView(boolean apply, boolean reset, View parent) { if (parent != null) { View view = parent.findViewById(mId); if (view != null && !mComparator.isEmpty(view)) { - mApplicator.apply(view, apply); + mApplicator.apply(parent, view, apply, reset); } } } @@ -375,14 +381,26 @@ public class NotificationHeaderUtil { } private interface ResultApplicator { - void apply(View view, boolean apply); + void apply(View parent, View view, boolean apply, boolean reset); } private static class VisibilityApplicator implements ResultApplicator { @Override - public void apply(View view, boolean apply) { + public void apply(View parent, View view, boolean apply, boolean reset) { view.setVisibility(apply ? View.GONE : View.VISIBLE); } } + + private static class AppNameApplicator extends VisibilityApplicator { + + @Override + public void apply(View parent, View view, boolean apply, boolean reset) { + if (reset && parent instanceof ConversationLayout) { + ConversationLayout layout = (ConversationLayout) parent; + apply = layout.shouldHideAppName(); + } + super.apply(parent, view, apply, reset); + } + } } 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 6f27ff30c5875..5ee4693a32bf0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java @@ -102,11 +102,11 @@ public class MessagingLayoutTransformState extends TransformState { MessagingGroup matchingGroup = pairs.get(ownGroup); if (!isGone(ownGroup)) { if (matchingGroup != null) { - transformGroups(ownGroup, matchingGroup, transformationAmount, to); + int totalTranslation = transformGroups(ownGroup, matchingGroup, + transformationAmount, to); if (lastPairedGroup == null) { lastPairedGroup = ownGroup; if (to){ - float totalTranslation = ownGroup.getTop() - matchingGroup.getTop(); currentTranslation = matchingGroup.getAvatar().getTranslationY() - totalTranslation; } else { @@ -229,14 +229,19 @@ public class MessagingLayoutTransformState extends TransformState { return result; } - private void transformGroups(MessagingGroup ownGroup, MessagingGroup otherGroup, + /** + * Transform two groups towards each other. + * + * @return the total transformation distance that the group goes through + */ + private int transformGroups(MessagingGroup ownGroup, MessagingGroup otherGroup, float transformationAmount, boolean to) { boolean useLinearTransformation = otherGroup.getIsolatedMessage() == null && !mTransformInfo.isAnimating(); transformView(transformationAmount, to, ownGroup.getSenderView(), otherGroup.getSenderView(), true /* sameAsAny */, useLinearTransformation); - transformView(transformationAmount, to, ownGroup.getAvatar(), otherGroup.getAvatar(), - true /* sameAsAny */, useLinearTransformation); + int totalAvatarTranslation = transformView(transformationAmount, to, ownGroup.getAvatar(), + otherGroup.getAvatar(), true /* sameAsAny */, useLinearTransformation); List ownMessages = ownGroup.getMessages(); List otherMessages = otherGroup.getMessages(); float previousTranslation = 0; @@ -284,6 +289,7 @@ public class MessagingLayoutTransformState extends TransformState { } } ownGroup.updateClipRect(); + return totalAvatarTranslation; } /**