diff options
27 files changed, 798 insertions, 533 deletions
diff --git a/config/hiddenapi-max-target-o.txt b/config/hiddenapi-max-target-o.txt index 023bf3876228..eefe493efbc4 100644 --- a/config/hiddenapi-max-target-o.txt +++ b/config/hiddenapi-max-target-o.txt @@ -91659,8 +91659,6 @@ Lcom/android/internal/R$dimen;->notification_expand_button_padding_top:I Lcom/android/internal/R$dimen;->notification_header_app_name_margin_start:I Lcom/android/internal/R$dimen;->notification_header_background_height:I Lcom/android/internal/R$dimen;->notification_header_expand_icon_size:I -Lcom/android/internal/R$dimen;->notification_header_height:I -Lcom/android/internal/R$dimen;->notification_header_icon_margin_end:I Lcom/android/internal/R$dimen;->notification_header_icon_size:I Lcom/android/internal/R$dimen;->notification_header_separating_margin:I Lcom/android/internal/R$dimen;->notification_header_shrink_min_width:I diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 4c08e759f3cf..113ec4df3c9f 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -4868,13 +4868,15 @@ public class Notification implements Parcelable mN.mUsesStandardHeader = false; } - private RemoteViews applyStandardTemplate(int resId, TemplateBindResult result) { - return applyStandardTemplate(resId, mParams.reset().fillTextsFrom(this), - result); + private RemoteViews applyStandardTemplate(int resId, int viewType, + TemplateBindResult result) { + return applyStandardTemplate(resId, + mParams.reset().viewType(viewType).fillTextsFrom(this), result); } private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p, TemplateBindResult result) { + p.headerless(resId == getBaseLayoutResource()); RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId); resetStandardTemplate(contentView); @@ -4884,7 +4886,7 @@ public class Notification implements Parcelable bindNotificationHeader(contentView, p); bindLargeIconAndReply(contentView, p, result); boolean showProgress = handleProgressBar(contentView, ex, p); - if (p.title != null) { + if (p.title != null && p.title.length() > 0) { contentView.setViewVisibility(R.id.title, View.VISIBLE); contentView.setTextViewText(R.id.title, processTextSpans(p.title)); setTextViewColorPrimary(contentView, R.id.title, p); @@ -5099,53 +5101,56 @@ public class Notification implements Parcelable } } - private void bindLargeIconAndReply(RemoteViews contentView, StandardTemplateParams p, - TemplateBindResult result) { + private void bindLargeIconAndReply(RemoteViews contentView, + @NonNull StandardTemplateParams p, + @Nullable TemplateBindResult result) { + if (result == null) { + result = new TemplateBindResult(); + } boolean largeIconShown = bindLargeIcon(contentView, p); boolean replyIconShown = bindReplyIcon(contentView, p); - boolean iconContainerVisible = largeIconShown || replyIconShown; - contentView.setViewVisibility(R.id.right_icon_container, - iconContainerVisible ? View.VISIBLE : View.GONE); - int marginEnd = calculateMarginEnd(largeIconShown, replyIconShown); - contentView.setViewLayoutMarginEnd(R.id.line1, marginEnd); - contentView.setViewLayoutMarginEnd(R.id.text, marginEnd); - contentView.setViewLayoutMarginEnd(R.id.progress, marginEnd); - if (result != null) { - result.setIconMarginEnd(marginEnd); - result.setRightIconContainerVisible(iconContainerVisible); + calculateLargeIconMarginEnd(largeIconShown, result); + calculateReplyIconMarginEnd(replyIconShown, result); + if (p.mHeaderless) { + // views in the headerless (collapsed) state + contentView.setViewLayoutMarginEnd(R.id.notification_standard_view_column, + result.getHeadingExtraMarginEnd()); + } else { + // views in states with a header (big states) + contentView.setInt(R.id.notification_header, "setTopLineExtraMarginEnd", + result.getHeadingExtraMarginEnd()); + contentView.setViewLayoutMarginEnd(R.id.line1, result.getTitleMarginEnd()); } } - private int calculateMarginEnd(boolean largeIconShown, boolean replyIconShown) { - int marginEnd = 0; + private void calculateLargeIconMarginEnd(boolean largeIconShown, + @NonNull TemplateBindResult result) { int contentMargin = mContext.getResources().getDimensionPixelSize( R.dimen.notification_content_margin_end); - int iconSize = mContext.getResources().getDimensionPixelSize( - R.dimen.notification_right_icon_size); - if (replyIconShown) { - // The size of the reply icon - marginEnd += iconSize; + int expanderSize = mContext.getResources().getDimensionPixelSize( + R.dimen.notification_header_expand_icon_size) - contentMargin; + int extraMarginEnd = 0; + if (largeIconShown) { + int iconSize = mContext.getResources().getDimensionPixelSize( + R.dimen.notification_right_icon_size); + extraMarginEnd = iconSize + contentMargin; + } + result.setRightIconState(largeIconShown, extraMarginEnd, expanderSize); + } + private void calculateReplyIconMarginEnd(boolean replyIconShown, + @NonNull TemplateBindResult result) { + int marginEnd = 0; + if (replyIconShown) { + int iconSize = mContext.getResources().getDimensionPixelSize( + R.dimen.notification_reply_icon_size); + int contentMargin = mContext.getResources().getDimensionPixelSize( + R.dimen.notification_content_margin_end); int replyInset = mContext.getResources().getDimensionPixelSize( R.dimen.notification_reply_inset); - // We're subtracting the inset of the reply icon to make sure it's - // aligned nicely on the right, and remove it from the following padding - marginEnd -= replyInset * 2; + marginEnd = iconSize + contentMargin - replyInset * 2; } - if (largeIconShown) { - // adding size of the right icon - marginEnd += iconSize; - - if (replyIconShown) { - // We also add some padding to the reply icon if it's around - marginEnd += contentMargin; - } - } - if (replyIconShown || largeIconShown) { - // The padding to the content - marginEnd += contentMargin; - } - return marginEnd; + result.setReplyIconState(replyIconShown, marginEnd); } /** @@ -5156,7 +5161,10 @@ public class Notification implements Parcelable if (mN.mLargeIcon == null && mN.largeIcon != null) { mN.mLargeIcon = Icon.createWithBitmap(mN.largeIcon); } - boolean showLargeIcon = mN.mLargeIcon != null && !p.hideLargeIcon; + // Hide the large icon in Heads Up view, because the icon is partly within header, + // which for HUNs will be hidden and cropped. + boolean showLargeIcon = mN.mLargeIcon != null && !p.hideLargeIcon + && p.mViewType != StandardTemplateParams.VIEW_TYPE_HEADS_UP; if (showLargeIcon) { contentView.setViewVisibility(R.id.right_icon, View.VISIBLE); contentView.setImageViewIcon(R.id.right_icon, mN.mLargeIcon); @@ -5170,7 +5178,7 @@ public class Notification implements Parcelable * @return if the reply icon is visible */ private boolean bindReplyIcon(RemoteViews contentView, StandardTemplateParams p) { - boolean actionVisible = !p.hideReplyIcon; + boolean actionVisible = !p.hideReplyIcon && !p.mHeaderless; Action action = null; if (actionVisible) { action = findReplyAction(); @@ -5375,10 +5383,10 @@ public class Notification implements Parcelable R.dimen.notification_content_margin); } - private RemoteViews applyStandardTemplateWithActions(int layoutId, + private RemoteViews applyStandardTemplateWithActions(int layoutId, int viewType, TemplateBindResult result) { - return applyStandardTemplateWithActions(layoutId, mParams.reset().fillTextsFrom(this), - result); + return applyStandardTemplateWithActions(layoutId, + mParams.reset().viewType(viewType).fillTextsFrom(this), result); } private static List<Notification.Action> filterOutContextualActions( @@ -5518,7 +5526,8 @@ public class Notification implements Parcelable return styleView; } } - return applyStandardTemplate(getBaseLayoutResource(), null /* result */); + return applyStandardTemplate(getBaseLayoutResource(), + StandardTemplateParams.VIEW_TYPE_NORMAL, null /* result */); } private boolean useExistingRemoteView() { @@ -5533,12 +5542,14 @@ public class Notification implements Parcelable RemoteViews result = null; if (mN.bigContentView != null && useExistingRemoteView()) { return mN.bigContentView; - } else if (mStyle != null) { + } + if (mStyle != null) { result = mStyle.makeBigContentView(); hideLine1Text(result); - } else if (mActions.size() != 0) { + } + if (result == null) { result = applyStandardTemplateWithActions(getBigBaseLayoutResource(), - null /* result */); + StandardTemplateParams.VIEW_TYPE_BIG, null /* result */); } makeHeaderExpanded(result); return result; @@ -5551,7 +5562,9 @@ public class Notification implements Parcelable * @hide */ public RemoteViews makeNotificationHeader() { - return makeNotificationHeader(mParams.reset().fillTextsFrom(this)); + return makeNotificationHeader(mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_MINIMIZED) + .fillTextsFrom(this)); } /** @@ -5624,7 +5637,9 @@ public class Notification implements Parcelable // We only want at most a single remote input history to be shown here, otherwise // the content would become squished. - StandardTemplateParams p = mParams.reset().fillTextsFrom(this) + StandardTemplateParams p = mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP) + .fillTextsFrom(this) .setMaxRemoteInputHistory(1); return applyStandardTemplateWithActions(getBigBaseLayoutResource(), p, @@ -5672,7 +5687,9 @@ public class Notification implements Parcelable } mN.extras = publicExtras; RemoteViews view; - StandardTemplateParams params = mParams.reset().fillTextsFrom(this); + StandardTemplateParams params = mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_PUBLIC) + .fillTextsFrom(this); if (isLowPriority) { params.forceDefaultColor(); } @@ -5696,6 +5713,7 @@ public class Notification implements Parcelable */ public RemoteViews makeLowPriorityContentView(boolean useRegularSubtext) { StandardTemplateParams p = mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_MINIMIZED) .forceDefaultColor() .fillTextsFrom(this); if (!useRegularSubtext || TextUtils.isEmpty(mParams.summaryText)) { @@ -6563,7 +6581,10 @@ public class Notification implements Parcelable } protected RemoteViews getStandardView(int layoutId) { - StandardTemplateParams p = mBuilder.mParams.reset().fillTextsFrom(mBuilder); + // TODO(jeffdq): set the view type based on the layout resource? + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_UNSPECIFIED) + .fillTextsFrom(mBuilder); return getStandardView(layoutId, p, null); } @@ -6892,7 +6913,8 @@ public class Notification implements Parcelable mBuilder.mN.largeIcon = null; } - StandardTemplateParams p = mBuilder.mParams.reset().fillTextsFrom(mBuilder); + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_BIG).fillTextsFrom(mBuilder); RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource(), p, null /* result */); if (mSummaryTextSet) { @@ -7106,11 +7128,13 @@ public class Notification implements Parcelable * @hide */ public RemoteViews makeBigContentView() { - StandardTemplateParams p = mBuilder.mParams.reset().fillTextsFrom(mBuilder).text(null); + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_BIG) + .fillTextsFrom(mBuilder).text(null); TemplateBindResult result = new TemplateBindResult(); RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource(), p, result); - contentView.setInt(R.id.big_text, "setImageEndMargin", result.getIconMarginEnd()); + contentView.setInt(R.id.big_text, "setImageEndMargin", result.getTextMarginEnd()); CharSequence bigTextText = mBuilder.processLegacyText(mBigText); if (TextUtils.isEmpty(bigTextText)) { @@ -7124,7 +7148,7 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.big_text, TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE); contentView.setBoolean(R.id.big_text, "setHasImage", - result.isRightIconContainerVisible()); + result.isReplyIconVisible()); return contentView; } @@ -7708,6 +7732,8 @@ public class Notification implements Parcelable Icon largeIcon = mBuilder.mN.mLargeIcon; TemplateBindResult bindResult = new TemplateBindResult(); StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(isCollapsed ? StandardTemplateParams.VIEW_TYPE_NORMAL + : StandardTemplateParams.VIEW_TYPE_BIG) .hasProgress(false) .title(conversationTitle) .text(null) @@ -7725,7 +7751,7 @@ public class Notification implements Parcelable if (!isConversationLayout) { // also update the end margin if there is an image contentView.setViewLayoutMarginEnd(R.id.notification_messaging, - bindResult.getIconMarginEnd()); + bindResult.getHeadingExtraMarginEnd()); } contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor", mBuilder.isColorized(p) @@ -8213,7 +8239,9 @@ public class Notification implements Parcelable * @hide */ public RemoteViews makeBigContentView() { - StandardTemplateParams p = mBuilder.mParams.reset().fillTextsFrom(mBuilder).text(null); + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_BIG) + .fillTextsFrom(mBuilder).text(null); TemplateBindResult result = new TemplateBindResult(); RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource(), p, result); @@ -8266,7 +8294,7 @@ public class Notification implements Parcelable mBuilder.setTextViewColorSecondary(contentView, rowIds[i], p); contentView.setViewPadding(rowIds[i], 0, topPadding, 0, 0); handleInboxImageMargin(contentView, rowIds[i], first, - result.getIconMarginEnd()); + result.getHeadingFullMarginEnd()); if (first) { onlyViewId = rowIds[i]; } else { @@ -8533,8 +8561,9 @@ public class Notification implements Parcelable } private RemoteViews makeMediaContentView() { - StandardTemplateParams p = mBuilder.mParams.reset().hasProgress(false).fillTextsFrom( - mBuilder); + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL) + .hasProgress(false).fillTextsFrom(mBuilder); RemoteViews view = mBuilder.applyStandardTemplate( R.layout.notification_template_material_media, p, null /* result */); @@ -8580,8 +8609,9 @@ public class Notification implements Parcelable if (!mBuilder.mN.hasLargeIcon() && actionCount <= actionsInCompact) { return null; } - StandardTemplateParams p = mBuilder.mParams.reset().hasProgress(false).fillTextsFrom( - mBuilder); + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_BIG) + .hasProgress(false).fillTextsFrom(mBuilder); RemoteViews big = mBuilder.applyStandardTemplate( R.layout.notification_template_material_big_media, p , null /* result */); @@ -8680,16 +8710,18 @@ public class Notification implements Parcelable } TemplateBindResult result = new TemplateBindResult(); RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions( - mBuilder.getBigBaseLayoutResource(), result); - buildIntoRemoteViewContent(remoteViews, headsUpContentView, result); + mBuilder.getBigBaseLayoutResource(), + StandardTemplateParams.VIEW_TYPE_HEADS_UP, result); + buildIntoRemoteViewContent(remoteViews, headsUpContentView, result, false); return remoteViews; } private RemoteViews makeStandardTemplateWithCustomContent(RemoteViews customContent) { TemplateBindResult result = new TemplateBindResult(); RemoteViews remoteViews = mBuilder.applyStandardTemplate( - mBuilder.getBaseLayoutResource(), result); - buildIntoRemoteViewContent(remoteViews, customContent, result); + mBuilder.getBaseLayoutResource(), + StandardTemplateParams.VIEW_TYPE_NORMAL, result); + buildIntoRemoteViewContent(remoteViews, customContent, result, true); return remoteViews; } @@ -8697,18 +8729,16 @@ public class Notification implements Parcelable RemoteViews bigContentView = mBuilder.mN.bigContentView == null ? mBuilder.mN.contentView : mBuilder.mN.bigContentView; - if (mBuilder.mActions.size() == 0) { - return makeStandardTemplateWithCustomContent(bigContentView); - } TemplateBindResult result = new TemplateBindResult(); RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions( - mBuilder.getBigBaseLayoutResource(), result); - buildIntoRemoteViewContent(remoteViews, bigContentView, result); + mBuilder.getBigBaseLayoutResource(), + StandardTemplateParams.VIEW_TYPE_BIG, result); + buildIntoRemoteViewContent(remoteViews, bigContentView, result, false); return remoteViews; } private void buildIntoRemoteViewContent(RemoteViews remoteViews, - RemoteViews customContent, TemplateBindResult result) { + RemoteViews customContent, TemplateBindResult result, boolean headerless) { int childIndex = -1; if (customContent != null) { // Need to clone customContent before adding, because otherwise it can no longer be @@ -8722,11 +8752,14 @@ public class Notification implements Parcelable remoteViews.setIntTag(R.id.notification_main_column, com.android.internal.R.id.notification_custom_view_index_tag, childIndex); - // also update the end margin if there is an image - Resources resources = mBuilder.mContext.getResources(); - int endMargin = resources.getDimensionPixelSize( - R.dimen.notification_content_margin_end) + result.getIconMarginEnd(); - remoteViews.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin); + if (!headerless) { + // also update the end margin to account for the large icon or expander + Resources resources = mBuilder.mContext.getResources(); + int endMargin = resources.getDimensionPixelSize( + R.dimen.notification_content_margin_end) + result.getTitleMarginEnd(); + remoteViews.setViewLayoutMarginEnd(R.id.notification_main_column, + endMargin); + } } /** @@ -10962,35 +10995,78 @@ public class Notification implements Parcelable * A result object where information about the template that was created is saved. */ private static class TemplateBindResult { - int mIconMarginEnd; - boolean mRightIconContainerVisible; + boolean mRightIconVisible; + int mRightIconMarginEnd; + int mExpanderSize; + boolean mReplyIconVisible; + int mReplyIconMarginEnd; /** - * Get the margin end that needs to be added to any fields that may overlap - * with the right actions. + * @return the margin end that needs to be added to the heading so that it won't overlap + * with the large icon. This value includes the space required to accommodate the large + * icon, but should be added to the space needed to accommodate the expander. This does + * not include the 16dp content margin that all notification views must have. */ - public int getIconMarginEnd() { - return mIconMarginEnd; + public int getHeadingExtraMarginEnd() { + return mRightIconMarginEnd; + } + + /** + * @return the margin end that needs to be added to the heading so that it won't overlap + * with the large icon. This value includes the space required to accommodate the large + * icon as well as the expander. This does not include the 16dp content margin that all + * notification views must have. + */ + public int getHeadingFullMarginEnd() { + return mRightIconMarginEnd + mExpanderSize; + } + + /** + * @return the margin end that needs to be added to the title text of the big state + * so that it won't overlap with either the large icon or the reply action. + */ + public int getTitleMarginEnd() { + return mRightIconVisible ? getHeadingFullMarginEnd() : mReplyIconMarginEnd; + } + + /** + * @return the margin end that needs to be added to the topmost content of the big state + * so that it won't overlap with the reply action. + */ + public int getTextMarginEnd() { + return mReplyIconMarginEnd; } /** * Is the icon container visible on the right size because of the reply button or the * right icon. */ - public boolean isRightIconContainerVisible() { - return mRightIconContainerVisible; + public boolean isReplyIconVisible() { + return mReplyIconVisible; } - public void setIconMarginEnd(int iconMarginEnd) { - this.mIconMarginEnd = iconMarginEnd; + public void setReplyIconState(boolean visible, int marginEnd) { + mReplyIconVisible = visible; + mReplyIconMarginEnd = marginEnd; } - public void setRightIconContainerVisible(boolean iconContainerVisible) { - mRightIconContainerVisible = iconContainerVisible; + public void setRightIconState(boolean visible, int marginEnd, int expanderSize) { + mRightIconVisible = visible; + mRightIconMarginEnd = marginEnd; + mExpanderSize = expanderSize; } } private static class StandardTemplateParams { + public static int VIEW_TYPE_UNSPECIFIED = 0; + public static int VIEW_TYPE_NORMAL = 1; + public static int VIEW_TYPE_BIG = 2; + public static int VIEW_TYPE_HEADS_UP = 3; + public static int VIEW_TYPE_MINIMIZED = 4; + public static int VIEW_TYPE_PUBLIC = 5; + + int mViewType = VIEW_TYPE_UNSPECIFIED; + boolean mHeaderless; boolean hasProgress = true; CharSequence title; CharSequence text; @@ -11003,6 +11079,8 @@ public class Notification implements Parcelable boolean forceDefaultColor = false; final StandardTemplateParams reset() { + mViewType = VIEW_TYPE_UNSPECIFIED; + mHeaderless = false; hasProgress = true; title = null; text = null; @@ -11014,6 +11092,16 @@ public class Notification implements Parcelable return this; } + final StandardTemplateParams viewType(int viewType) { + mViewType = viewType; + return this; + } + + public StandardTemplateParams headerless(boolean headerless) { + mHeaderless = headerless; + return this; + } + final StandardTemplateParams hasProgress(boolean hasProgress) { this.hasProgress = hasProgress; return this; diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java index 2bd3d46d389a..f7fbb1ce0ab9 100644 --- a/core/java/android/view/NotificationHeaderView.java +++ b/core/java/android/view/NotificationHeaderView.java @@ -27,6 +27,7 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; import android.util.AttributeSet; +import android.widget.FrameLayout; import android.widget.RemoteViews; import com.android.internal.R; @@ -41,15 +42,14 @@ import java.util.ArrayList; * @hide */ @RemoteViews.RemoteView -public class NotificationHeaderView extends ViewGroup { - private final int mChildMinWidth; +public class NotificationHeaderView extends FrameLayout { private final int mContentEndMargin; + private final int mHeadingEndMargin; private OnClickListener mExpandClickListener; private HeaderTouchListener mTouchListener = new HeaderTouchListener(); private NotificationTopLineView mTopLineView; private NotificationExpandButton mExpandButton; private CachingIconView mIcon; - private int mHeaderTextMarginEnd; private Drawable mBackground; private boolean mEntireHeaderClickable; private boolean mExpandOnlyOnButton; @@ -82,8 +82,8 @@ public class NotificationHeaderView extends ViewGroup { int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); Resources res = getResources(); - mChildMinWidth = res.getDimensionPixelSize(R.dimen.notification_header_shrink_min_width); mContentEndMargin = res.getDimensionPixelSize(R.dimen.notification_content_margin_end); + mHeadingEndMargin = res.getDimensionPixelSize(R.dimen.notification_heading_margin_end); mEntireHeaderClickable = res.getBoolean(R.bool.config_notificationHeaderClickableForExpand); } @@ -96,108 +96,6 @@ public class NotificationHeaderView extends ViewGroup { setClipToPadding(false); } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int givenWidth = MeasureSpec.getSize(widthMeasureSpec); - final int givenHeight = MeasureSpec.getSize(heightMeasureSpec); - int wrapContentWidthSpec = MeasureSpec.makeMeasureSpec(givenWidth, - MeasureSpec.AT_MOST); - int wrapContentHeightSpec = MeasureSpec.makeMeasureSpec(givenHeight, - MeasureSpec.AT_MOST); - int totalWidth = getPaddingStart(); - int iconWidth = getPaddingEnd(); - for (int i = 0; i < getChildCount(); i++) { - final View child = getChildAt(i); - if (child.getVisibility() == GONE) { - // We'll give it the rest of the space in the end - continue; - } - final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); - int childWidthSpec = getChildMeasureSpec(wrapContentWidthSpec, - lp.leftMargin + lp.rightMargin, lp.width); - int childHeightSpec = getChildMeasureSpec(wrapContentHeightSpec, - lp.topMargin + lp.bottomMargin, lp.height); - child.measure(childWidthSpec, childHeightSpec); - // Icons that should go at the end - if (child == mExpandButton) { - iconWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth(); - } else { - totalWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth(); - } - } - - // Ensure that there is at least enough space for the icons - int endMargin = Math.max(mHeaderTextMarginEnd, iconWidth); - if (totalWidth > givenWidth - endMargin) { - int overFlow = totalWidth - givenWidth + endMargin; - // We are overflowing; shrink the top line - shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mTopLineView, - mChildMinWidth); - } - setMeasuredDimension(givenWidth, givenHeight); - } - - private int shrinkViewForOverflow(int heightSpec, int overFlow, View targetView, - int minimumWidth) { - final int oldWidth = targetView.getMeasuredWidth(); - if (overFlow > 0 && targetView.getVisibility() != GONE && oldWidth > minimumWidth) { - // we're still too big - int newSize = Math.max(minimumWidth, oldWidth - overFlow); - int childWidthSpec = MeasureSpec.makeMeasureSpec(newSize, MeasureSpec.AT_MOST); - targetView.measure(childWidthSpec, heightSpec); - overFlow -= oldWidth - newSize; - } - return overFlow; - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int left = getPaddingStart(); - int end = getMeasuredWidth(); - int childCount = getChildCount(); - int ownHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); - for (int i = 0; i < childCount; i++) { - View child = getChildAt(i); - if (child.getVisibility() == GONE) { - continue; - } - int childHeight = child.getMeasuredHeight(); - MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams(); - int layoutLeft; - int layoutRight; - int top = (int) (getPaddingTop() + (ownHeight - childHeight) / 2.0f); - int bottom = top + childHeight; - // Icons that should go at the end - if (child == mExpandButton) { - if (end == getMeasuredWidth()) { - layoutRight = end - mContentEndMargin; - } else { - layoutRight = end - params.getMarginEnd(); - } - layoutLeft = layoutRight - child.getMeasuredWidth(); - end = layoutLeft - params.getMarginStart(); - } else { - left += params.getMarginStart(); - int right = left + child.getMeasuredWidth(); - layoutLeft = left; - layoutRight = right; - left = right + params.getMarginEnd(); - } - if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) { - int ltrLeft = layoutLeft; - layoutLeft = getWidth() - layoutRight; - layoutRight = getWidth() - ltrLeft; - } - child.layout(layoutLeft, top, layoutRight, bottom); - } - updateTouchListener(); - } - - @Override - public LayoutParams generateLayoutParams(AttributeSet attrs) { - return new MarginLayoutParams(getContext(), attrs); - } - /** * Set a {@link Drawable} to be displayed as a background on the header. */ @@ -252,23 +150,34 @@ public class NotificationHeaderView extends ViewGroup { } /** - * Sets the margin end for the text portion of the header, excluding right-aligned elements - * @param headerTextMarginEnd margin size + * Sets the extra margin at the end of the top line of left-aligned text + icons. + * This value will have the margin required to accommodate the expand button added to it. + * + * @param extraMarginEnd extra margin */ @RemotableViewMethod - public void setHeaderTextMarginEnd(int headerTextMarginEnd) { - if (mHeaderTextMarginEnd != headerTextMarginEnd) { - mHeaderTextMarginEnd = headerTextMarginEnd; - requestLayout(); - } + public void setTopLineExtraMarginEnd(int extraMarginEnd) { + mTopLineView.setHeaderTextMarginEnd(extraMarginEnd + mHeadingEndMargin); + } + + /** + * Get the current margin end value for the header text. + * Add this to {@link #getTopLineBaseMarginEnd()} to get the total margin of the top line. + * + * @return extra margin + */ + public int getTopLineExtraMarginEnd() { + return mTopLineView.getHeaderTextMarginEnd() - mHeadingEndMargin; } /** - * Get the current margin end value for the header text - * @return margin size + * Get the base margin at the end of the top line view. + * Add this to {@link #getTopLineExtraMarginEnd()} to get the total margin of the top line. + * + * @return base margin */ - public int getHeaderTextMarginEnd() { - return mHeaderTextMarginEnd; + public int getTopLineBaseMarginEnd() { + return mHeadingEndMargin; } /** diff --git a/core/java/android/view/NotificationTopLineView.java b/core/java/android/view/NotificationTopLineView.java index 24748222b3af..f6073ca2f0b2 100644 --- a/core/java/android/view/NotificationTopLineView.java +++ b/core/java/android/view/NotificationTopLineView.java @@ -40,7 +40,8 @@ public class NotificationTopLineView extends ViewGroup { private final int mGravityY; private final int mChildMinWidth; private final int mContentEndMargin; - private View mAppName; + @Nullable private View mAppName; + @Nullable private View mTitle; private View mHeaderText; private View mSecondaryHeaderText; private OnClickListener mFeedbackListener; @@ -92,6 +93,7 @@ public class NotificationTopLineView extends ViewGroup { protected void onFinishInflate() { super.onFinishInflate(); mAppName = findViewById(R.id.app_name_text); + mTitle = findViewById(R.id.title); mHeaderText = findViewById(R.id.header_text); mSecondaryHeaderText = findViewById(R.id.header_text_secondary); mProfileBadge = findViewById(R.id.profile_badge); @@ -144,9 +146,17 @@ public class NotificationTopLineView extends ViewGroup { int endMargin = Math.max(mHeaderTextMarginEnd, iconWidth); if (totalWidth > givenWidth - endMargin) { int overFlow = totalWidth - givenWidth + endMargin; - // We are overflowing, lets shrink the app name first - overFlow = shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mAppName, - mChildMinWidth); + if (mAppName != null) { + // We are overflowing, lets shrink the app name first + overFlow = shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mAppName, + mChildMinWidth); + } + + if (mTitle != null) { + // still overflowing, we shrink the title text + overFlow = shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mTitle, + mChildMinWidth); + } // still overflowing, we shrink the header text overFlow = shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mHeaderText, 0); @@ -298,6 +308,13 @@ public class NotificationTopLineView extends ViewGroup { return mHeaderTextMarginEnd; } + /** + * Set padding at the start of the view. + */ + public void setPaddingStart(int paddingStart) { + setPaddingRelative(paddingStart, getPaddingTop(), getPaddingEnd(), getPaddingBottom()); + } + private class HeaderTouchListener implements OnTouchListener { private Rect mFeedbackRect; diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java index 9bb45012b61a..f42d5da30b19 100644 --- a/core/java/com/android/internal/widget/MediaNotificationView.java +++ b/core/java/com/android/internal/widget/MediaNotificationView.java @@ -98,12 +98,14 @@ public class MediaNotificationView extends FrameLayout { mMainColumn.setLayoutParams(params); reMeasure = true; } + // TODO(b/172652345): validate all this logic (especially positioning of expand button) // margin for the entire header line int headerMarginEnd = imageEndMargin; // margin for the header text (not including the expand button and other icons) - int headerTextMarginEnd = size + imageEndMargin; - if (headerTextMarginEnd != mHeader.getHeaderTextMarginEnd()) { - mHeader.setHeaderTextMarginEnd(headerTextMarginEnd); + int headerExtraMarginEnd = Math.max(0, + size + imageEndMargin - mHeader.getTopLineBaseMarginEnd()); + if (headerExtraMarginEnd != mHeader.getTopLineExtraMarginEnd()) { + mHeader.setTopLineExtraMarginEnd(headerExtraMarginEnd); reMeasure = true; } params = (MarginLayoutParams) mHeader.getLayoutParams(); diff --git a/core/res/res/drawable/notification_icon_circle.xml b/core/res/res/drawable/notification_icon_circle.xml new file mode 100644 index 000000000000..b10a52d41b6a --- /dev/null +++ b/core/res/res/drawable/notification_icon_circle.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> + <solid android:color="#333" /> +</shape> diff --git a/core/res/res/drawable/notification_large_icon_outline.xml b/core/res/res/drawable/notification_large_icon_outline.xml new file mode 100644 index 000000000000..bac03d2fe1c4 --- /dev/null +++ b/core/res/res/drawable/notification_large_icon_outline.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="5dp" /> + <solid android:color="#00000000" /> +</shape> diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml index bf66e69b52d3..552a1bd6aa2e 100644 --- a/core/res/res/layout/notification_material_action_list.xml +++ b/core/res/res/layout/notification_material_action_list.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2014 The Android Open Source Project +<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2014 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,50 +13,54 @@ limitations under the License. --> -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/actions_container" +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/actions_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/notification_action_list_margin_top" + android:layout_gravity="bottom" + > + + <LinearLayout + android:id="@+id/actions_container_layout" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/notification_action_list_margin_top" - android:layout_gravity="bottom"> - - <LinearLayout - android:id="@+id/actions_container_layout" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="end" + android:gravity="end" + android:orientation="horizontal" + android:paddingEnd="@dimen/bubble_gone_padding_end" + android:background="@color/notification_action_list_background_color" + > + + <com.android.internal.widget.NotificationActionListLayout + android:id="@+id/actions" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="@dimen/notification_action_list_height" android:orientation="horizontal" - android:paddingEnd="@dimen/bubble_gone_padding_end" - android:background="@color/notification_action_list_background_color" + android:gravity="center_vertical" + android:paddingStart="@dimen/notification_actions_padding_start" + android:visibility="gone" > + <!-- actions will be added here --> + </com.android.internal.widget.NotificationActionListLayout> + + <ImageView + android:id="@+id/snooze_button" + android:layout_width="@dimen/notification_actions_icon_size" + android:layout_height="@dimen/notification_actions_icon_size" + android:layout_gravity="center_vertical|end" + android:visibility="gone" + android:scaleType="centerInside" + /> - <com.android.internal.widget.NotificationActionListLayout - android:id="@+id/actions" - android:layout_width="0dp" - android:layout_weight="1" - android:layout_height="@dimen/notification_action_list_height" - android:orientation="horizontal" - android:gravity="center_vertical" - android:visibility="gone" - > - <!-- actions will be added here --> - </com.android.internal.widget.NotificationActionListLayout> - - <ImageView - android:id="@+id/snooze_button" - android:layout_width="48dp" - android:layout_height="48dp" - android:layout_gravity="center_vertical|end" - android:visibility="gone" - android:scaleType="centerInside" - /> - <ImageView - android:id="@+id/bubble_button" - android:layout_width="48dp" - android:layout_height="48dp" - android:layout_gravity="center_vertical|end" - android:visibility="gone" - android:scaleType="centerInside" - /> + <ImageView + android:id="@+id/bubble_button" + android:layout_width="@dimen/notification_actions_icon_size" + android:layout_height="@dimen/notification_actions_icon_size" + android:layout_gravity="center_vertical|end" + android:visibility="gone" + android:scaleType="centerInside" + /> </LinearLayout> </FrameLayout> diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml index d11875e0f890..a26473ad6010 100644 --- a/core/res/res/layout/notification_template_header.xml +++ b/core/res/res/layout/notification_template_header.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2015 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,40 +13,66 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<!-- extends ViewGroup --> +<!-- extends FrameLayout --> <NotificationHeaderView xmlns:android="http://schemas.android.com/apk/res/android" - android:theme="@style/Theme.DeviceDefault.Notification" android:id="@+id/notification_header" - android:orientation="horizontal" android:layout_width="wrap_content" - android:layout_height="@dimen/notification_header_height" + android:layout_height="@dimen/notification_header_solo_height" + android:layout_marginBottom="@dimen/notification_header_margin_bottom" android:clipChildren="false" - style="?attr/notificationHeaderStyle"> - <!-- Wrapper used to expand the width of the "space" containing the icon programmatically --> - <FrameLayout - android:id="@+id/header_icon_container" - android:layout_width="wrap_content" - android:layout_height="wrap_content"> + android:gravity="center_vertical" + android:orientation="horizontal" + android:theme="@style/Theme.DeviceDefault.Notification" + > - <com.android.internal.widget.CachingIconView - android:id="@+id/icon" - android:layout_width="?attr/notificationHeaderIconSize" - android:layout_height="?attr/notificationHeaderIconSize" - android:layout_marginEnd="@dimen/notification_header_icon_margin_end" - android:layout_gravity="center" + <com.android.internal.widget.CachingIconView + android:id="@+id/icon" + android:layout_width="@dimen/notification_icon_circle_size" + android:layout_height="@dimen/notification_icon_circle_size" + android:layout_gravity="center_vertical|start" + android:layout_marginStart="@dimen/notification_icon_circle_start" + android:background="@drawable/notification_icon_circle" + android:padding="@dimen/notification_icon_circle_padding" /> - </FrameLayout> - <include layout="@layout/notification_template_top_line" /> + + <!-- extends ViewGroup --> + <NotificationTopLineView + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/notification_top_line" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="center_vertical" + android:clipChildren="false" + android:gravity="center_vertical" + android:paddingEnd="@dimen/notification_heading_margin_end" + android:paddingStart="@dimen/notification_content_margin_start" + android:theme="@style/Theme.DeviceDefault.Notification" + > + + <TextView + android:id="@+id/app_name_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/notification_header_separating_margin" + android:singleLine="true" + android:textAppearance="?attr/notificationHeaderTextAppearance" + android:visibility="?attr/notificationHeaderAppNameVisibility" + /> + + <include layout="@layout/notification_top_line_views" /> + + </NotificationTopLineView> + <com.android.internal.widget.NotificationExpandButton android:id="@+id/expand_button" - android:background="@null" android:layout_width="@dimen/notification_header_expand_icon_size" android:layout_height="@dimen/notification_header_expand_icon_size" - android:layout_marginStart="4dp" + android:layout_gravity="center_vertical|end" + android:contentDescription="@string/expand_button_content_description_collapsed" android:paddingTop="@dimen/notification_expand_button_padding_top" + android:scaleType="center" android:visibility="gone" - android:contentDescription="@string/expand_button_content_description_collapsed" /> -</NotificationHeaderView> +</NotificationHeaderView> diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index 34c7fa734f21..e5de55ddd07b 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2014 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,25 +19,102 @@ android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="wrap_content" - android:tag="base" > - <include layout="@layout/notification_template_header" /> - <LinearLayout - android:id="@+id/notification_main_column" + android:minHeight="@dimen/notification_headerless_min_height" + android:tag="base" + > + + <com.android.internal.widget.CachingIconView + android:id="@+id/icon" + android:layout_width="@dimen/notification_icon_circle_size" + android:layout_height="@dimen/notification_icon_circle_size" + android:layout_gravity="center_vertical|start" + android:layout_marginStart="@dimen/notification_icon_circle_start" + android:background="@drawable/notification_icon_circle" + android:padding="@dimen/notification_icon_circle_padding" + /> + + <com.android.internal.widget.RemeasuringLinearLayout + android:id="@+id/notification_standard_view_column" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="top" - android:layout_marginStart="@dimen/notification_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" - android:layout_marginTop="@dimen/notification_content_margin_top" - android:layout_marginBottom="@dimen/notification_content_margin" - android:orientation="vertical" > - <include layout="@layout/notification_template_part_line1" /> - <include layout="@layout/notification_template_text" /> - <include + android:layout_gravity="center_vertical" + android:layout_marginBottom="@dimen/notification_headerless_margin_vertical" + android:layout_marginTop="@dimen/notification_headerless_margin_vertical" + android:orientation="vertical" + > + + <!-- extends ViewGroup --> + <NotificationTopLineView + android:id="@+id/notification_top_line" + android:layout_width="wrap_content" + android:layout_height="@dimen/notification_headerless_line_height" + android:layout_marginEnd="@dimen/notification_heading_margin_end" + android:layout_marginStart="@dimen/notification_content_margin_start" + android:clipChildren="false" + android:theme="@style/Theme.DeviceDefault.Notification" + > + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + android:singleLine="true" + android:textAlignment="viewStart" + android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title" + /> + + <include layout="@layout/notification_top_line_views" /> + + </NotificationTopLineView> + + <com.android.internal.widget.RemeasuringLinearLayout + android:id="@+id/notification_main_column" android:layout_width="match_parent" - android:layout_height="@dimen/notification_progress_bar_height" - android:layout_marginTop="@dimen/notification_progress_margin_top" - layout="@layout/notification_template_progress" /> - </LinearLayout> - <include layout="@layout/notification_template_right_icon" /> + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/notification_heading_margin_end" + android:layout_marginStart="@dimen/notification_content_margin_start" + android:orientation="vertical" + > + + <include + layout="@layout/notification_template_text" + android:layout_width="match_parent" + android:layout_height="@dimen/notification_headerless_line_height" + android:layout_marginTop="0dp" + /> + + <include + layout="@layout/notification_template_progress" + android:layout_width="match_parent" + android:layout_height="@dimen/notification_headerless_line_height" + /> + + </com.android.internal.widget.RemeasuringLinearLayout> + </com.android.internal.widget.RemeasuringLinearLayout> + + <ImageView + android:id="@+id/right_icon" + android:layout_width="@dimen/notification_right_icon_size" + android:layout_height="@dimen/notification_right_icon_size" + android:layout_gravity="center_vertical|end" + android:layout_marginEnd="@dimen/notification_header_expand_icon_size" + android:background="@drawable/notification_large_icon_outline" + android:importantForAccessibility="no" + android:scaleType="centerCrop" + /> + + <com.android.internal.widget.NotificationExpandButton + android:id="@+id/expand_button" + android:layout_width="@dimen/notification_header_expand_icon_size" + android:layout_height="@dimen/notification_header_expand_icon_size" + android:layout_gravity="center_vertical|end" + android:background="@null" + android:contentDescription="@string/expand_button_content_description_collapsed" + android:paddingTop="@dimen/notification_expand_button_padding_top" + android:scaleType="center" + android:visibility="gone" + /> + </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml index 21068908ffe8..c9592a793cdf 100644 --- a/core/res/res/layout/notification_template_material_big_base.xml +++ b/core/res/res/layout/notification_template_material_big_base.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2014 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,19 +20,30 @@ android:layout_height="wrap_content" android:orientation="vertical" android:clipChildren="false" - android:tag="big" > + android:tag="big" + > + <LinearLayout - android:id="@+id/notification_action_list_margin_target" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/notification_action_list_height" - android:orientation="vertical" > + android:id="@+id/notification_action_list_margin_target" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/notification_action_list_height" + android:orientation="vertical" + > + <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" - android:layout_gravity="top" > - <include layout="@layout/notification_template_header" /> + android:layout_gravity="top" + > + + <include + layout="@layout/notification_template_header" + android:layout_width="match_parent" + android:layout_height="@dimen/notification_header_big_height" + /> + <LinearLayout android:id="@+id/notification_main_column" android:layout_width="match_parent" @@ -41,28 +51,41 @@ android:layout_marginStart="@dimen/notification_content_margin_start" android:layout_marginEnd="@dimen/notification_content_margin_end" android:layout_marginTop="@dimen/notification_content_margin_top" - android:orientation="vertical" > + android:orientation="vertical" + > + <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_template_text" /> + <include android:layout_width="match_parent" android:layout_height="@dimen/notification_progress_bar_height" android:layout_marginTop="@dimen/notification_progress_margin_top" - layout="@layout/notification_template_progress" /> + layout="@layout/notification_template_progress" + /> </LinearLayout> + <include layout="@layout/notification_template_right_icon" /> + <include layout="@layout/notification_template_reply_icon" /> </FrameLayout> + <ViewStub android:layout="@layout/notification_material_reply_text" android:id="@+id/notification_material_reply_container" android:layout_width="match_parent" - android:layout_height="wrap_content" /> - <include layout="@layout/notification_template_smart_reply_container" + android:layout_height="wrap_content" + /> + + <include + layout="@layout/notification_template_smart_reply_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_content_margin_start" android:layout_marginEnd="@dimen/notification_content_margin_end" - android:layout_marginTop="@dimen/notification_content_margin" /> + android:layout_marginTop="@dimen/notification_content_margin" + /> + <include layout="@layout/notification_material_action_list" /> </LinearLayout> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml index 6c47c2c51601..bbe49e5d06fc 100644 --- a/core/res/res/layout/notification_template_material_big_media.xml +++ b/core/res/res/layout/notification_template_material_big_media.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2014 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,22 +24,28 @@ android:tag="bigMediaNarrow" > <!-- The size will actually be determined at runtime --> - <ImageView android:id="@+id/right_icon" + <ImageView + android:id="@+id/right_icon" android:layout_width="0dp" android:layout_height="0dp" android:layout_gravity="top|end" android:scaleType="centerCrop" - /> - <include layout="@layout/notification_template_header" + /> + + <include + layout="@layout/notification_template_header" android:layout_width="match_parent" android:layout_height="@dimen/media_notification_header_height" - android:layout_gravity="start"/> + android:layout_gravity="start" + /> + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:id="@+id/notification_media_content" > + <LinearLayout android:id="@+id/notification_main_column" android:layout_width="match_parent" @@ -52,38 +57,49 @@ android:minHeight="@dimen/notification_min_content_height" android:orientation="vertical" > + <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_template_text" /> </LinearLayout> + <LinearLayout android:id="@+id/media_actions" android:orientation="horizontal" android:layoutDirection="ltr" - style="@style/NotificationMediaActionContainer" > + style="@style/NotificationMediaActionContainer" + > + <include layout="@layout/notification_material_media_action" android:id="@+id/action0" - /> + /> + <include layout="@layout/notification_material_media_action" android:id="@+id/action1" - /> + /> + <include layout="@layout/notification_material_media_action" android:id="@+id/action2" - /> + /> + <include layout="@layout/notification_material_media_action" android:id="@+id/action3" - /> + /> + <include layout="@layout/notification_material_media_action" android:id="@+id/action4" - /> + /> </LinearLayout> - <ViewStub android:id="@+id/notification_media_seekbar_container" + + <ViewStub + android:id="@+id/notification_media_seekbar_container" android:layout_width="match_parent" android:layout_height="wrap_content" - /> + /> </LinearLayout> </com.android.internal.widget.MediaNotificationView> diff --git a/core/res/res/layout/notification_template_material_big_picture.xml b/core/res/res/layout/notification_template_material_big_picture.xml index 7a1cc1eff167..dd975eb27ac9 100644 --- a/core/res/res/layout/notification_template_material_big_picture.xml +++ b/core/res/res/layout/notification_template_material_big_picture.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2014 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,61 +14,84 @@ ~ limitations under the License --> -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="match_parent" android:tag="bigPicture" android:clipChildren="false" > - <include layout="@layout/notification_template_header" /> + + <include + layout="@layout/notification_template_header" + android:layout_width="match_parent" + android:layout_height="@dimen/notification_header_big_height" + /> + <include layout="@layout/notification_template_right_icon" /> + + <include layout="@layout/notification_template_reply_icon" /> + <LinearLayout - android:id="@+id/notification_action_list_margin_target" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="top" - android:layout_marginTop="@dimen/notification_content_margin_top" - android:clipToPadding="false" - android:orientation="vertical" - > + android:id="@+id/notification_action_list_margin_target" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="top" + android:layout_marginTop="@dimen/notification_content_margin_top" + android:clipToPadding="false" + android:orientation="vertical" + > + <LinearLayout android:id="@+id/notification_main_column" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_content_margin_start" android:layout_marginEnd="@dimen/notification_content_margin_end" - android:orientation="vertical"> - <include layout="@layout/notification_template_part_line1"/> - <include layout="@layout/notification_template_progress" - android:layout_width="match_parent" - android:layout_height="@dimen/notification_progress_bar_height" - android:layout_marginTop="@dimen/notification_progress_margin_top"/> - <include layout="@layout/notification_template_text"/> - </LinearLayout> - <ImageView - android:id="@+id/big_picture" - android:layout_width="match_parent" - android:layout_height="0dp" - android:adjustViewBounds="true" - android:layout_weight="1" - android:layout_marginTop="13dp" - android:layout_marginStart="@dimen/notification_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" - android:scaleType="centerCrop" - /> + android:orientation="vertical" + > - <ViewStub android:layout="@layout/notification_material_reply_text" - android:id="@+id/notification_material_reply_container" + <include layout="@layout/notification_template_part_line1" /> + + <include + layout="@layout/notification_template_progress" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="@dimen/notification_progress_bar_height" + android:layout_marginTop="@dimen/notification_progress_margin_top" /> - <include layout="@layout/notification_template_smart_reply_container" + + <include layout="@layout/notification_template_text" /> + </LinearLayout> + + <ImageView + android:id="@+id/big_picture" + android:layout_width="match_parent" + android:layout_height="0dp" + android:adjustViewBounds="true" + android:layout_weight="1" + android:layout_marginTop="13dp" + android:layout_marginStart="@dimen/notification_content_margin_start" + android:layout_marginEnd="@dimen/notification_content_margin_end" + android:scaleType="centerCrop" + /> + + <ViewStub + android:layout="@layout/notification_material_reply_text" + android:id="@+id/notification_material_reply_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + /> + + <include + layout="@layout/notification_template_smart_reply_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_content_margin_start" android:layout_marginEnd="@dimen/notification_content_margin_end" - android:layout_marginTop="@dimen/notification_content_margin" /> + android:layout_marginTop="@dimen/notification_content_margin" + /> + <include layout="@layout/notification_material_action_list" /> </LinearLayout> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml index d5ea96f6bc16..117991bc6beb 100644 --- a/core/res/res/layout/notification_template_material_big_text.xml +++ b/core/res/res/layout/notification_template_material_big_text.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2014 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,24 +14,31 @@ ~ limitations under the License --> -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipChildren="false" android:tag="bigText" > - <include layout="@layout/notification_template_header" /> + + <include + layout="@layout/notification_template_header" + android:layout_width="match_parent" + android:layout_height="@dimen/notification_header_big_height" + /> <com.android.internal.widget.RemeasuringLinearLayout - android:id="@+id/notification_action_list_margin_target" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="top" - android:layout_marginTop="@dimen/notification_content_margin_top" - android:layout_marginBottom="@dimen/notification_action_list_height" - android:clipToPadding="false" - android:orientation="vertical"> + android:id="@+id/notification_action_list_margin_target" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="top" + android:layout_marginTop="@dimen/notification_content_margin_top" + android:layout_marginBottom="@dimen/notification_action_list_height" + android:clipToPadding="false" + android:orientation="vertical" + > <com.android.internal.widget.RemeasuringLinearLayout android:id="@+id/notification_main_column" @@ -46,13 +52,19 @@ android:orientation="vertical" android:layout_weight="1" > + <include layout="@layout/notification_template_part_line1" /> - <include layout="@layout/notification_template_progress" + + <include + layout="@layout/notification_template_progress" android:layout_width="match_parent" android:layout_height="@dimen/notification_progress_bar_height" android:layout_marginTop="@dimen/notification_progress_margin_top" - android:layout_marginBottom="6dp"/> - <com.android.internal.widget.ImageFloatingTextView android:id="@+id/big_text" + android:layout_marginBottom="6dp" + /> + + <com.android.internal.widget.ImageFloatingTextView + android:id="@+id/big_text" style="@style/Widget.DeviceDefault.Notification.Text" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -64,17 +76,25 @@ /> </com.android.internal.widget.RemeasuringLinearLayout> - <ViewStub android:layout="@layout/notification_material_reply_text" - android:id="@+id/notification_material_reply_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - <include layout="@layout/notification_template_smart_reply_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="@dimen/notification_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" - android:layout_marginTop="@dimen/notification_content_margin" /> + <ViewStub + android:layout="@layout/notification_material_reply_text" + android:id="@+id/notification_material_reply_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + /> + + <include + layout="@layout/notification_template_smart_reply_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/notification_content_margin_start" + android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginTop="@dimen/notification_content_margin" + /> + <include layout="@layout/notification_material_action_list" /> </com.android.internal.widget.RemeasuringLinearLayout> + <include layout="@layout/notification_template_right_icon" /> + <include layout="@layout/notification_template_reply_icon" /> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml index 48cfa073d08b..5e3d6471fdf7 100644 --- a/core/res/res/layout/notification_template_material_conversation.xml +++ b/core/res/res/layout/notification_template_material_conversation.xml @@ -359,8 +359,8 @@ /> <com.android.internal.widget.NotificationExpandButton android:id="@+id/expand_button" - android:layout_width="@dimen/notification_header_expand_icon_size" - android:layout_height="@dimen/notification_header_expand_icon_size" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_gravity="center" android:drawable="@drawable/ic_expand_notification" android:clickable="false" diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml index eb8925819cd3..4bf70736b883 100644 --- a/core/res/res/layout/notification_template_material_inbox.xml +++ b/core/res/res/layout/notification_template_material_inbox.xml @@ -129,4 +129,5 @@ <include layout="@layout/notification_material_action_list" /> </LinearLayout> <include layout="@layout/notification_template_right_icon" /> + <include layout="@layout/notification_template_reply_icon" /> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_messaging.xml b/core/res/res/layout/notification_template_material_messaging.xml index 10c750972961..f37bda5cc5f6 100644 --- a/core/res/res/layout/notification_template_material_messaging.xml +++ b/core/res/res/layout/notification_template_material_messaging.xml @@ -57,5 +57,6 @@ android:layout_marginEnd="@dimen/notification_content_margin_end" /> <include layout="@layout/notification_material_action_list" /> </com.android.internal.widget.RemeasuringLinearLayout> - <include layout="@layout/notification_template_right_icon"/> + <include layout="@layout/notification_template_right_icon" /> + <include layout="@layout/notification_template_reply_icon" /> </com.android.internal.widget.MessagingLayout> diff --git a/core/res/res/layout/notification_template_reply_icon.xml b/core/res/res/layout/notification_template_reply_icon.xml new file mode 100644 index 000000000000..695f7c8b5c6f --- /dev/null +++ b/core/res/res/layout/notification_template_reply_icon.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2015 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<ImageView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/reply_icon_action" + android:layout_width="@dimen/notification_reply_icon_size" + android:layout_height="@dimen/notification_reply_icon_size" + android:layout_gravity="top|end" + android:layout_marginEnd="8dp" + android:layout_marginTop="@dimen/notification_content_margin_top" + android:contentDescription="@string/notification_reply_button_accessibility" + android:scaleType="centerCrop" + android:src="@drawable/ic_reply_notification" /> + diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml index ee416ad36b8a..d22d4c20dad2 100644 --- a/core/res/res/layout/notification_template_right_icon.xml +++ b/core/res/res/layout/notification_template_right_icon.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2015 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,29 +13,15 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<!-- The view only has 8dp padding at the end instead of notification_content_margin_end, - since the reply icon has an inset of 8dp and we want it to visually start at the start of the - icon. --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/right_icon_container" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/notification_content_margin_top" - android:layout_marginEnd="8dp" - android:layout_gravity="top|end"> - <ImageView android:id="@+id/right_icon" - android:layout_width="@dimen/notification_right_icon_size" - android:layout_height="@dimen/notification_right_icon_size" - android:layout_gravity="top|end" - android:layout_marginEnd="8dp" - android:scaleType="centerCrop" - android:importantForAccessibility="no" /> - <ImageView android:id="@+id/reply_icon_action" - android:layout_width="@dimen/notification_right_icon_size" - android:layout_height="@dimen/notification_right_icon_size" - android:layout_gravity="top|end" - android:contentDescription="@string/notification_reply_button_accessibility" - android:scaleType="centerCrop" - android:src="@drawable/ic_reply_notification"/> -</LinearLayout> - +<ImageView + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/right_icon" + android:layout_width="@dimen/notification_right_icon_size" + android:layout_height="@dimen/notification_right_icon_size" + android:layout_gravity="top|end" + android:layout_marginEnd="@dimen/notification_header_expand_icon_size" + android:layout_marginTop="@dimen/notification_right_icon_big_margin_top" + android:background="@drawable/notification_large_icon_outline" + android:importantForAccessibility="no" + android:scaleType="centerCrop" + /> diff --git a/core/res/res/layout/notification_template_text.xml b/core/res/res/layout/notification_template_text.xml index 01b14ae0592d..b72f6bf02c88 100644 --- a/core/res/res/layout/notification_template_text.xml +++ b/core/res/res/layout/notification_template_text.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2016 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<com.android.internal.widget.ImageFloatingTextView xmlns:android="http://schemas.android.com/apk/res/android" +<com.android.internal.widget.ImageFloatingTextView + xmlns:android="http://schemas.android.com/apk/res/android" style="@style/Widget.DeviceDefault.Notification.Text" android:id="@+id/text" android:layout_width="match_parent" diff --git a/core/res/res/layout/notification_template_top_line.xml b/core/res/res/layout/notification_top_line_views.xml index 0786e138559f..5d3feeb0725d 100644 --- a/core/res/res/layout/notification_template_top_line.xml +++ b/core/res/res/layout/notification_top_line_views.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2015 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,25 +13,13 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<!-- extends ViewGroup --> -<NotificationTopLineView - xmlns:android="http://schemas.android.com/apk/res/android" - android:theme="@style/Theme.DeviceDefault.Notification" - android:id="@+id/notification_top_line" - android:layout_width="wrap_content" - android:layout_height="@dimen/notification_header_height" - android:clipChildren="false" - > - <TextView - android:id="@+id/app_name_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="?attr/notificationHeaderTextAppearance" - android:layout_marginStart="@dimen/notification_header_app_name_margin_start" - android:layout_marginEnd="@dimen/notification_header_separating_margin" - android:visibility="?attr/notificationHeaderAppNameVisibility" - android:singleLine="true" - /> +<!-- + This layout file should be included inside a NotificationTopLineView, usually after either a + <TextView android:id="@+id/app_name_text"/> or <TextView android:id="@+id/title"/> +--> +<merge + xmlns:android="http://schemas.android.com/apk/res/android"> + <TextView android:id="@+id/header_text_secondary_divider" android:layout_width="wrap_content" @@ -41,7 +28,9 @@ android:layout_marginStart="@dimen/notification_header_separating_margin" android:layout_marginEnd="@dimen/notification_header_separating_margin" android:text="@string/notification_header_divider_symbol" - android:visibility="gone"/> + android:visibility="gone" + /> + <TextView android:id="@+id/header_text_secondary" android:layout_width="wrap_content" @@ -50,7 +39,9 @@ android:layout_marginStart="@dimen/notification_header_separating_margin" android:layout_marginEnd="@dimen/notification_header_separating_margin" android:visibility="gone" - android:singleLine="true"/> + android:singleLine="true" + /> + <TextView android:id="@+id/header_text_divider" android:layout_width="wrap_content" @@ -59,7 +50,9 @@ android:layout_marginStart="@dimen/notification_header_separating_margin" android:layout_marginEnd="@dimen/notification_header_separating_margin" android:text="@string/notification_header_divider_symbol" - android:visibility="gone"/> + android:visibility="gone" + /> + <TextView android:id="@+id/header_text" android:layout_width="wrap_content" @@ -68,7 +61,9 @@ android:layout_marginStart="@dimen/notification_header_separating_margin" android:layout_marginEnd="@dimen/notification_header_separating_margin" android:visibility="gone" - android:singleLine="true"/> + android:singleLine="true" + /> + <TextView android:id="@+id/time_divider" android:layout_width="wrap_content" @@ -78,7 +73,9 @@ android:layout_marginEnd="@dimen/notification_header_separating_margin" android:text="@string/notification_header_divider_symbol" android:singleLine="true" - android:visibility="gone"/> + android:visibility="gone" + /> + <DateTimeView android:id="@+id/time" android:textAppearance="@style/TextAppearance.Material.Notification.Time" @@ -88,7 +85,9 @@ android:layout_marginEnd="@dimen/notification_header_separating_margin" android:showRelative="true" android:singleLine="true" - android:visibility="gone" /> + android:visibility="gone" + /> + <ViewStub android:id="@+id/chronometer" android:layout_width="wrap_content" @@ -98,6 +97,7 @@ android:layout="@layout/notification_template_part_chronometer" android:visibility="gone" /> + <ImageView android:id="@+id/alerted_icon" android:layout_width="@dimen/notification_alerted_size" @@ -108,7 +108,8 @@ android:visibility="gone" android:contentDescription="@string/notification_alerted_content_description" android:src="@drawable/ic_notifications_alerted" - /> + /> + <ImageButton android:id="@+id/feedback" android:layout_width="@dimen/notification_feedback_size" @@ -121,7 +122,8 @@ android:background="?android:selectableItemBackgroundBorderless" android:visibility="gone" android:contentDescription="@string/notification_feedback_indicator" - /> + /> + <ImageView android:id="@+id/profile_badge" android:layout_width="@dimen/notification_badge_size" @@ -132,5 +134,5 @@ android:visibility="gone" android:contentDescription="@string/notification_work_profile_content_description" /> -</NotificationTopLineView> +</merge> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 544be54eb785..a5e5fbf763f7 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -207,12 +207,15 @@ <!-- Default padding for dialogs. --> <dimen name="dialog_padding">16dp</dimen> - <!-- The margin on the start of the content view --> - <dimen name="notification_content_margin_start">16dp</dimen> + <!-- The margin on the start of the content view (accommodates the icon) --> + <dimen name="notification_content_margin_start">52dp</dimen> - <!-- The margin on the end of the content view. --> + <!-- The margin on the end of most content views (ignores the expander) --> <dimen name="notification_content_margin_end">16dp</dimen> + <!-- The margin on the end of the top-line content views (accommodates the expander) --> + <dimen name="notification_heading_margin_end">48dp</dimen> + <!-- The inset of the reply icon. --> <dimen name="notification_reply_inset">8dp</dimen> @@ -228,6 +231,13 @@ <!-- The height of the notification action list --> <dimen name="notification_action_emphasized_height">48dp</dimen> + <!-- The padding of the actions in non-conversation layout. For conversations, the analogous + value is calculated in ConversationLayout#updateActionListPadding() --> + <dimen name="notification_actions_padding_start">36dp</dimen> + + <!-- The size of icons for visual actions in the notification_material_action_list --> + <dimen name="notification_actions_icon_size">48dp</dimen> + <!-- Size of the stroke with for the emphasized notification button style --> <dimen name="emphasized_button_stroke_width">1dp</dimen> @@ -243,8 +253,11 @@ <!-- The top margin before the notification progress bar. --> <dimen name="notification_progress_margin_top">8dp</dimen> - <!-- height of the notification header (for icon and package name) --> - <dimen name="notification_header_height">50dp</dimen> + <!-- height of the notification header when the notification is alone (minimized / groups) --> + <dimen name="notification_header_solo_height">48dp</dimen> + + <!-- height of the notification header when in a "big" layout --> + <dimen name="notification_header_big_height">56dp</dimen> <!-- The height of the background for a notification header on a group --> <dimen name="notification_header_background_height">49.5dp</dimen> @@ -258,12 +271,18 @@ <!-- The margin at the bottom of the notification header. --> <dimen name="notification_header_margin_bottom">0dp</dimen> - <!-- The end margin after the application icon in the notification header --> - <dimen name="notification_header_icon_margin_end">3dp</dimen> - <!-- size (width and height) of the icon in the notification header --> <dimen name="notification_header_icon_size">18dp</dimen> + <!-- size (width and height) of the circle around the icon in the notification header --> + <dimen name="notification_icon_circle_size">24dp</dimen> + + <!-- padding between the notification icon and the circle containing it --> + <dimen name="notification_icon_circle_padding">4dp</dimen> + + <!-- start margin of the icon circle in the notification view --> + <dimen name="notification_icon_circle_start">16dp</dimen> + <!-- size (width and height) of the icon in the notification header --> <dimen name="notification_header_icon_size_ambient">18dp</dimen> @@ -276,12 +295,21 @@ <!-- The margin before and after each of the items in the conversation header. --> <dimen name="notification_conversation_header_separating_margin">4dp</dimen> - <!-- The absolute size of the notification expand icon. -2 for wrap_content. --> - <dimen name="notification_header_expand_icon_size">-2px</dimen> + <!-- The absolute size of the notification expand icon. --> + <dimen name="notification_header_expand_icon_size">48dp</dimen> <!-- The top padding for the notification expand button. --> <dimen name="notification_expand_button_padding_top">1dp</dimen> + <!-- vertical margin for the headerless notification content --> + <dimen name="notification_headerless_margin_vertical">18dp</dimen> + + <!-- The height of each of the 1 or 2 lines in the headerless notification template --> + <dimen name="notification_headerless_line_height">20sp</dimen> + + <!-- vertical margin for the headerless notification content --> + <dimen name="notification_headerless_min_height">56dp</dimen> + <!-- Height of a small notification in the status bar --> <dimen name="notification_min_height">106dp</dimen> @@ -310,7 +338,7 @@ <dimen name="media_notification_expanded_image_margin_bottom">20dp</dimen> <!-- The absolute height for the header in a media notification. --> - <dimen name="media_notification_header_height">@dimen/notification_header_height</dimen> + <dimen name="media_notification_header_height">@dimen/notification_header_big_height</dimen> <!-- The margin of the content to an image--> <dimen name="notification_content_image_margin_end">8dp</dimen> @@ -679,7 +707,11 @@ <!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.--> <dimen name="notification_media_image_max_width">280dp</dimen> <!-- The size of the right icon --> - <dimen name="notification_right_icon_size">36dp</dimen> + <dimen name="notification_right_icon_size">52dp</dimen> + <!-- The top margin of the right icon in the "big" notification states --> + <dimen name="notification_right_icon_big_margin_top">16dp</dimen> + <!-- The size of the reply icon --> + <dimen name="notification_reply_icon_size">36dp</dimen> <!-- The alpha of a disabled notification button --> <item type="dimen" format="float" name="notification_action_disabled_alpha">0.5</item> @@ -702,6 +734,8 @@ <dimen name="messaging_avatar_size">@dimen/notification_right_icon_size</dimen> <dimen name="conversation_avatar_size">52dp</dimen> + <!-- start margin of the icon circle in the conversation's skin of the header --> + <dimen name="conversation_icon_circle_start">28dp</dimen> <!-- Start of the content in the conversation template --> <dimen name="conversation_content_start">80dp</dimen> <!-- Size of the expand button in the conversation layout --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index fba431c66f53..065aef50f297 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -218,6 +218,7 @@ <java-symbol type="id" name="inbox_text6" /> <java-symbol type="id" name="status_bar_latest_event_content" /> <java-symbol type="id" name="notification_main_column" /> + <java-symbol type="id" name="notification_standard_view_column" /> <java-symbol type="id" name="sms_short_code_confirm_message" /> <java-symbol type="id" name="sms_short_code_detail_layout" /> <java-symbol type="id" name="sms_short_code_detail_message" /> @@ -2871,14 +2872,13 @@ <java-symbol type="dimen" name="notification_header_shrink_min_width" /> <java-symbol type="dimen" name="notification_content_margin_start" /> <java-symbol type="dimen" name="notification_content_margin_end" /> + <java-symbol type="dimen" name="notification_heading_margin_end" /> <java-symbol type="dimen" name="notification_reply_inset" /> <java-symbol type="dimen" name="notification_content_margin_top" /> <java-symbol type="dimen" name="notification_content_margin" /> <java-symbol type="dimen" name="notification_header_background_height" /> - <java-symbol type="dimen" name="notification_header_height" /> <java-symbol type="dimen" name="notification_header_expand_icon_size" /> <java-symbol type="dimen" name="notification_expand_button_padding_top" /> - <java-symbol type="dimen" name="notification_header_icon_margin_end" /> <java-symbol type="dimen" name="notification_header_icon_size" /> <java-symbol type="dimen" name="notification_header_app_name_margin_start" /> <java-symbol type="dimen" name="notification_header_separating_margin" /> @@ -3379,6 +3379,7 @@ <java-symbol type="dimen" name="notification_media_image_max_width"/> <java-symbol type="dimen" name="notification_media_image_max_height"/> <java-symbol type="dimen" name="notification_right_icon_size"/> + <java-symbol type="dimen" name="notification_reply_icon_size"/> <java-symbol type="dimen" name="notification_custom_view_max_image_height"/> <java-symbol type="dimen" name="notification_custom_view_max_image_width"/> @@ -3399,8 +3400,6 @@ <java-symbol type="bool" name="config_allowEscrowTokenForTrustAgent"/> <java-symbol type="string" name="config_defaultTrustAgent" /> - <!-- Time picker --> - <java-symbol type="id" name="right_icon_container"/> <java-symbol type="id" name="reply_icon_action"/> <java-symbol type="id" name="toggle_mode"/> <java-symbol type="id" name="input_mode"/> @@ -3935,8 +3934,9 @@ <java-symbol type="dimen" name="importance_ring_anim_max_stroke_width" /> <java-symbol type="dimen" name="importance_ring_size" /> <java-symbol type="dimen" name="conversation_icon_size_badged" /> + <java-symbol type="dimen" name="conversation_icon_circle_start" /> + <java-symbol type="dimen" name="notification_icon_circle_start" /> - <java-symbol type="id" name="header_icon_container" /> <java-symbol type="attr" name="notificationHeaderTextAppearance" /> <java-symbol type="string" name="conversation_single_line_name_display" /> <java-symbol type="string" name="conversation_single_line_image_placeholder" /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java index 25c8e7feb9b2..216b83f2b4d5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java @@ -33,6 +33,7 @@ import com.android.systemui.statusbar.notification.row.NotificationContentView; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Objects; /** * A Util to manage {@link android.view.NotificationHeaderView} objects and their redundancies. @@ -324,13 +325,15 @@ public class NotificationHeaderUtil { @Override public boolean compare(View parent, View child, Object parentData, Object childData) { TextView parentView = (TextView) parent; + CharSequence parentText = parentView == null ? "" : parentView.getText(); TextView childView = (TextView) child; - return parentView.getText().equals(childView.getText()); + CharSequence childText = childView == null ? "" : childView.getText(); + return Objects.equals(parentText, childText); } @Override public boolean isEmpty(View view) { - return TextUtils.isEmpty(((TextView) view).getText()); + return view == null || TextUtils.isEmpty(((TextView) view).getText()); } } @@ -369,7 +372,9 @@ public class NotificationHeaderUtil { @Override public void apply(View parent, View view, boolean apply, boolean reset) { - view.setVisibility(apply ? View.GONE : View.VISIBLE); + if (view != null) { + view.setVisibility(apply ? View.GONE : View.VISIBLE); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index 79c300782ad9..328774550f24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -318,30 +318,13 @@ public class NotificationContentView extends FrameLayout { // We need to update the expanded and the collapsed header to have exactly the same with to // have the expand buttons laid out at the same location. NotificationHeaderView contractedHeader = mContractedWrapper.getNotificationHeader(); - if (contractedHeader != null) { - if (mExpandedChild != null - && mExpandedWrapper.getNotificationHeader() != null) { - NotificationHeaderView expandedHeader = mExpandedWrapper.getNotificationHeader(); - - int headerTextMargin = expandedHeader.getHeaderTextMarginEnd(); - if (headerTextMargin != contractedHeader.getHeaderTextMarginEnd()) { - contractedHeader.setHeaderTextMarginEnd(headerTextMargin); - return true; - } - } else { - int paddingEnd = mNotificationContentMarginEnd; - if (contractedHeader.getPaddingEnd() != paddingEnd) { - contractedHeader.setPadding( - contractedHeader.isLayoutRtl() - ? paddingEnd - : contractedHeader.getPaddingLeft(), - contractedHeader.getPaddingTop(), - contractedHeader.isLayoutRtl() - ? contractedHeader.getPaddingLeft() - : paddingEnd, - contractedHeader.getPaddingBottom()); - return true; - } + if (contractedHeader != null && mExpandedWrapper != null + && mExpandedWrapper.getNotificationHeader() != null) { + NotificationHeaderView expandedHeader = mExpandedWrapper.getNotificationHeader(); + int headerTextMargin = expandedHeader.getTopLineExtraMarginEnd(); + if (headerTextMargin != contractedHeader.getTopLineExtraMarginEnd()) { + contractedHeader.setTopLineExtraMarginEnd(headerTextMargin); + return true; } } return false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java index 5aeacaba6f64..bde3d5a1e174 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java @@ -28,7 +28,6 @@ import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -63,8 +62,8 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { private TextView mAppNameText; private ImageView mWorkProfileImage; private View mAudiblyAlertedIcon; - private FrameLayout mIconContainer; private View mFeedbackIcon; + private View mRightIcon; private boolean mIsLowPriority; private boolean mTransformLowPriorityTitle; @@ -103,11 +102,11 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { } protected void resolveHeaderViews() { - mIconContainer = mView.findViewById(com.android.internal.R.id.header_icon_container); mIcon = mView.findViewById(com.android.internal.R.id.icon); mHeaderText = mView.findViewById(com.android.internal.R.id.header_text); mAppNameText = mView.findViewById(com.android.internal.R.id.app_name_text); mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button); + mRightIcon = mView.findViewById(com.android.internal.R.id.right_icon); mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge); mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header); mNotificationTopLine = mView.findViewById(com.android.internal.R.id.notification_top_line); @@ -145,6 +144,9 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { updateCropToPaddingForImageViews(); Notification notification = row.getEntry().getSbn().getNotification(); mIcon.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon()); + if (mRightIcon != null) { + mRightIcon.setClipToOutline(true); + } // We need to reset all views that are no longer transforming in case a view was previously // transformed, but now we decided to transform its container instead. @@ -165,19 +167,16 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { MarginLayoutParams layoutParams = (MarginLayoutParams) mAppNameText.getLayoutParams(); layoutParams.setMarginStart(0); } - if (mIconContainer != null) { - MarginLayoutParams layoutParams = (MarginLayoutParams) mIconContainer.getLayoutParams(); - layoutParams.width = - mIconContainer.getContext().getResources().getDimensionPixelSize( - com.android.internal.R.dimen.conversation_content_start); - final int marginStart = - mIconContainer.getContext().getResources().getDimensionPixelSize( - com.android.internal.R.dimen.notification_content_margin_start); - layoutParams.setMarginStart(marginStart * -1); + if (mNotificationTopLine != null) { + int paddingStart = mNotificationTopLine.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.conversation_content_start); + mNotificationTopLine.setPaddingStart(paddingStart); } if (mIcon != null) { MarginLayoutParams layoutParams = (MarginLayoutParams) mIcon.getLayoutParams(); - layoutParams.setMarginEnd(0); + int marginStart = mIcon.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.conversation_icon_circle_start); + layoutParams.setMarginStart(marginStart); } } @@ -189,20 +188,20 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { com.android.internal.R.style.TextAppearance_DeviceDefault_Notification_Info); mAppNameText.setTextAppearance(textAppearance); MarginLayoutParams layoutParams = (MarginLayoutParams) mAppNameText.getLayoutParams(); - final int marginStart = mAppNameText.getContext().getResources().getDimensionPixelSize( + final int marginStart = mAppNameText.getResources().getDimensionPixelSize( com.android.internal.R.dimen.notification_header_app_name_margin_start); layoutParams.setMarginStart(marginStart); } - if (mIconContainer != null) { - MarginLayoutParams layoutParams = (MarginLayoutParams) mIconContainer.getLayoutParams(); - layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; - layoutParams.setMarginStart(0); + if (mNotificationTopLine != null) { + int paddingStart = mNotificationTopLine.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.notification_content_margin_start); + mNotificationTopLine.setPaddingStart(paddingStart); } if (mIcon != null) { MarginLayoutParams layoutParams = (MarginLayoutParams) mIcon.getLayoutParams(); - final int marginEnd = mIcon.getContext().getResources().getDimensionPixelSize( - com.android.internal.R.dimen.notification_header_icon_margin_end); - layoutParams.setMarginEnd(marginEnd); + int marginStart = mIcon.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.notification_icon_circle_start); + layoutParams.setMarginStart(marginStart); } } diff --git a/packages/SystemUI/tools/lint/baseline.xml b/packages/SystemUI/tools/lint/baseline.xml index 096a63901b9d..3e494032b8e2 100644 --- a/packages/SystemUI/tools/lint/baseline.xml +++ b/packages/SystemUI/tools/lint/baseline.xml @@ -2909,17 +2909,6 @@ <issue id="UnusedResources" - message="The resource `R.dimen.notification_header_height` appears to be unused" - errorLine1=" <dimen name="notification_header_height">53dp</dimen>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="res/values/dimens.xml" - line="473" - column="12"/> - </issue> - - <issue - id="UnusedResources" message="The resource `R.dimen.speed_bump_height` appears to be unused" errorLine1=" <dimen name="speed_bump_height">16dp</dimen>" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> |