summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/Notification.java2
-rw-r--r--core/java/android/view/NotificationHeaderView.java8
-rw-r--r--core/java/com/android/internal/widget/CachingIconView.java49
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java105
-rw-r--r--core/java/com/android/internal/widget/MessagingPropertyAnimator.java2
5 files changed, 148 insertions, 18 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e137acf4dc70..9b42fa2012e1 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5817,7 +5817,7 @@ public class Notification implements Parcelable
PorterDuff.Mode.SRC_ATOP);
}
- contentView.setInt(R.id.notification_header, "setOriginalIconColor",
+ contentView.setInt(R.id.icon, "setOriginalIconColor",
colorable ? color : NotificationHeaderView.NO_COLOR);
}
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 18e0132e2c4e..0359f3b4fde7 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -65,7 +65,6 @@ public class NotificationHeaderView extends ViewGroup {
private View mMicIcon;
private View mAppOps;
private View mAudiblyAlertedIcon;
- private int mIconColor;
private boolean mExpanded;
private boolean mShowExpandButtonAtEnd;
private boolean mShowWorkBadgeAtEnd;
@@ -315,13 +314,8 @@ public class NotificationHeaderView extends ViewGroup {
updateTouchListener();
}
- @RemotableViewMethod
- public void setOriginalIconColor(int color) {
- mIconColor = color;
- }
-
public int getOriginalIconColor() {
- return mIconColor;
+ return mIcon.getOriginalIconColor();
}
public int getOriginalNotificationColor() {
diff --git a/core/java/com/android/internal/widget/CachingIconView.java b/core/java/com/android/internal/widget/CachingIconView.java
index bd0623e1144e..84cde1b84e14 100644
--- a/core/java/com/android/internal/widget/CachingIconView.java
+++ b/core/java/com/android/internal/widget/CachingIconView.java
@@ -46,6 +46,9 @@ public class CachingIconView extends ImageView {
private boolean mForceHidden;
private int mDesiredVisibility;
private Consumer<Integer> mOnVisibilityChangedListener;
+ private Consumer<Boolean> mOnForceHiddenChangedListener;
+ private int mIconColor;
+ private boolean mWillBeForceHidden;
@UnsupportedAppUsage
public CachingIconView(Context context, @Nullable AttributeSet attrs) {
@@ -184,10 +187,18 @@ public class CachingIconView extends ImageView {
/**
* Set the icon to be forcibly hidden, even when it's visibility is changed to visible.
+ * This is necessary since we still want to keep certain views hidden when their visibility
+ * is modified from other sources like the shelf.
*/
public void setForceHidden(boolean forceHidden) {
- mForceHidden = forceHidden;
- updateVisibility();
+ if (forceHidden != mForceHidden) {
+ mForceHidden = forceHidden;
+ mWillBeForceHidden = false;
+ updateVisibility();
+ if (mOnForceHiddenChangedListener != null) {
+ mOnForceHiddenChangedListener.accept(forceHidden);
+ }
+ }
}
@Override
@@ -209,4 +220,38 @@ public class CachingIconView extends ImageView {
public void setOnVisibilityChangedListener(Consumer<Integer> listener) {
mOnVisibilityChangedListener = listener;
}
+
+ public void setOnForceHiddenChangedListener(Consumer<Boolean> listener) {
+ mOnForceHiddenChangedListener = listener;
+ }
+
+
+ public boolean isForceHidden() {
+ return mForceHidden;
+ }
+
+ @RemotableViewMethod
+ public void setOriginalIconColor(int color) {
+ mIconColor = color;
+ }
+
+ public int getOriginalIconColor() {
+ return mIconColor;
+ }
+
+ /**
+ * @return if the view will be forceHidden after an animation
+ */
+ public boolean willBeForceHidden() {
+ return mWillBeForceHidden;
+ }
+
+ /**
+ * Set that this view will be force hidden after an animation
+ *
+ * @param forceHidden if it will be forcehidden
+ */
+ public void setWillBeForceHidden(boolean forceHidden) {
+ mWillBeForceHidden = forceHidden;
+ }
}
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index bedf55d52391..1336ec412cdb 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -18,6 +18,8 @@ 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 static com.android.internal.widget.MessagingPropertyAnimator.ALPHA_IN;
+import static com.android.internal.widget.MessagingPropertyAnimator.ALPHA_OUT;
import android.annotation.AttrRes;
import android.annotation.NonNull;
@@ -106,7 +108,7 @@ public class ConversationLayout extends FrameLayout
private CharSequence mNameReplacement;
private boolean mIsCollapsed;
private ImageResolver mImageResolver;
- private ImageView mConversationIcon;
+ private CachingIconView mConversationIcon;
private View mConversationIconContainer;
private int mConversationIconTopPadding;
private int mConversationIconTopPaddingExpandedGroup;
@@ -114,7 +116,7 @@ public class ConversationLayout extends FrameLayout
private int mExpandedGroupMessagePaddingNoAppName;
private TextView mConversationText;
private View mConversationIconBadge;
- private ImageView mConversationIconBadgeBg;
+ private CachingIconView mConversationIconBadgeBg;
private Icon mLargeIcon;
private View mExpandButtonContainer;
private ViewGroup mExpandButtonAndContentContainer;
@@ -125,7 +127,7 @@ public class ConversationLayout extends FrameLayout
private int mConversationAvatarSize;
private int mConversationAvatarSizeExpanded;
private CachingIconView mIcon;
- private View mImportanceRingView;
+ private CachingIconView mImportanceRingView;
private int mExpandedGroupSideMargin;
private int mExpandedGroupSideMarginFacePile;
private View mConversationFacePile;
@@ -140,11 +142,15 @@ public class ConversationLayout extends FrameLayout
private int mContentMarginEnd;
private Rect mMessagingClipRect;
private ObservableTextView mAppName;
+ private ViewGroup mActions;
+ private int mConversationContentStart;
+ private int mInternalButtonPadding;
private boolean mAppNameGone;
private int mFacePileAvatarSize;
private int mFacePileAvatarSizeExpandedGroup;
private int mFacePileProtectionWidth;
private int mFacePileProtectionWidthExpanded;
+ private boolean mImportantConversation;
public ConversationLayout(@NonNull Context context) {
super(context);
@@ -168,6 +174,7 @@ public class ConversationLayout extends FrameLayout
protected void onFinishInflate() {
super.onFinishInflate();
mMessagingLinearLayout = findViewById(R.id.notification_messaging);
+ mActions = findViewById(R.id.actions);
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
@@ -186,9 +193,41 @@ public class ConversationLayout extends FrameLayout
mConversationIconBadge = findViewById(R.id.conversation_icon_badge);
mConversationIconBadgeBg = findViewById(R.id.conversation_icon_badge_bg);
mIcon.setOnVisibilityChangedListener((visibility) -> {
- // Always keep the badge visibility in sync with the icon. This is necessary in cases
- // Where the icon is being hidden externally like in group children.
- mConversationIconBadge.setVisibility(visibility);
+
+ // Let's hide the background directly or in an animated way
+ boolean isGone = visibility == GONE;
+ int oldVisibility = mConversationIconBadgeBg.getVisibility();
+ boolean wasGone = oldVisibility == GONE;
+ if (wasGone != isGone) {
+ // Keep the badge gone state in sync with the icon. This is necessary in cases
+ // Where the icon is being hidden externally like in group children.
+ mConversationIconBadgeBg.animate().cancel();
+ mConversationIconBadgeBg.setVisibility(visibility);
+ }
+
+ // Let's handle the importance ring which can also be be gone normally
+ oldVisibility = mImportanceRingView.getVisibility();
+ wasGone = oldVisibility == GONE;
+ visibility = !mImportantConversation ? GONE : visibility;
+ isGone = visibility == GONE;
+ if (wasGone != isGone) {
+ // Keep the badge visibility in sync with the icon. This is necessary in cases
+ // Where the icon is being hidden externally like in group children.
+ mImportanceRingView.animate().cancel();
+ mImportanceRingView.setVisibility(visibility);
+ }
+ });
+ // When the small icon is gone, hide the rest of the badge
+ mIcon.setOnForceHiddenChangedListener((forceHidden) -> {
+ animateViewForceHidden(mConversationIconBadgeBg, forceHidden);
+ animateViewForceHidden(mImportanceRingView, forceHidden);
+ });
+
+ // When the conversation icon is gone, hide the whole badge
+ mConversationIcon.setOnForceHiddenChangedListener((forceHidden) -> {
+ animateViewForceHidden(mConversationIconBadgeBg, forceHidden);
+ animateViewForceHidden(mImportanceRingView, forceHidden);
+ animateViewForceHidden(mIcon, forceHidden);
});
mConversationText = findViewById(R.id.conversation_text);
mExpandButtonContainer = findViewById(R.id.expand_button_container);
@@ -238,6 +277,33 @@ public class ConversationLayout extends FrameLayout
mAppName.setOnVisibilityChangedListener((visibility) -> {
onAppNameVisibilityChanged();
});
+ mConversationContentStart = getResources().getDimensionPixelSize(
+ R.dimen.conversation_content_start);
+ mInternalButtonPadding
+ = getResources().getDimensionPixelSize(R.dimen.button_padding_horizontal_material)
+ + getResources().getDimensionPixelSize(R.dimen.button_inset_horizontal_material);
+ }
+
+ private void animateViewForceHidden(CachingIconView view, boolean forceHidden) {
+ boolean nowForceHidden = view.willBeForceHidden() || view.isForceHidden();
+ if (forceHidden == nowForceHidden) {
+ // We are either already forceHidden or will be
+ return;
+ }
+ view.animate().cancel();
+ view.setWillBeForceHidden(forceHidden);
+ view.animate()
+ .scaleX(forceHidden ? 0.5f : 1.0f)
+ .scaleY(forceHidden ? 0.5f : 1.0f)
+ .alpha(forceHidden ? 0.0f : 1.0f)
+ .setInterpolator(forceHidden ? ALPHA_OUT : ALPHA_IN)
+ .setDuration(160);
+ if (view.getVisibility() != VISIBLE) {
+ view.setForceHidden(forceHidden);
+ } else {
+ view.animate().withEndAction(() -> view.setForceHidden(forceHidden));
+ }
+ view.animate().start();
}
@RemotableViewMethod
@@ -255,9 +321,14 @@ public class ConversationLayout extends FrameLayout
*/
@RemotableViewMethod
public void setIsImportantConversation(boolean isImportantConversation) {
+ mImportantConversation = isImportantConversation;
mImportanceRingView.setVisibility(isImportantConversation ? VISIBLE : GONE);
}
+ public boolean isImportantConversation() {
+ return mImportantConversation;
+ }
+
/**
* Set this layout to show the collapsed representation.
*
@@ -363,7 +434,6 @@ public class ConversationLayout extends FrameLayout
private void updateConversationLayout() {
// Set avatar and name
CharSequence conversationText = mConversationTitle;
- // TODO: display the secondary text somewhere
if (mIsOneToOne) {
// Let's resolve the icon / text from the last sender
mConversationIcon.setVisibility(VISIBLE);
@@ -418,6 +488,27 @@ public class ConversationLayout extends FrameLayout
updateIconPositionAndSize();
updateImageMessages();
updatePaddingsBasedOnContentAvailability();
+ updateActionListPadding();
+ }
+
+ private void updateActionListPadding() {
+ if (mActions == null) {
+ return;
+ }
+ View firstAction = mActions.getChildAt(0);
+ if (firstAction != null) {
+ // Let's visually position the first action where the content starts
+ int paddingStart = mConversationContentStart;
+
+ MarginLayoutParams layoutParams = (MarginLayoutParams) firstAction.getLayoutParams();
+ paddingStart -= layoutParams.getMarginStart();
+ paddingStart -= mInternalButtonPadding;
+
+ mActions.setPaddingRelative(paddingStart,
+ mActions.getPaddingTop(),
+ mActions.getPaddingEnd(),
+ mActions.getPaddingBottom());
+ }
}
private void updateImageMessages() {
diff --git a/core/java/com/android/internal/widget/MessagingPropertyAnimator.java b/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
index 7703cb0f13db..a3a75c098a00 100644
--- a/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
+++ b/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
@@ -32,7 +32,7 @@ import com.android.internal.R;
*/
public class MessagingPropertyAnimator implements View.OnLayoutChangeListener {
private static final long APPEAR_ANIMATION_LENGTH = 210;
- private static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
+ public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
private static final int TAG_TOP_ANIMATOR = R.id.tag_top_animator;
private static final int TAG_TOP = R.id.tag_top_override;