From defc5d9b1d186280cf67a3f599256d67ed28f270 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Tue, 27 Oct 2020 09:11:13 -0400 Subject: [PATCH 1/3] Remove the smart reply container from the base template; I believe they are never used Test: atest SystemUITests Change-Id: Ieca42376381133c07692134dae60e025da0bd3d5 --- core/res/res/layout/notification_template_material_base.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index 221bcf6a800c6..34c7fa734f210 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -39,10 +39,6 @@ android:layout_height="@dimen/notification_progress_bar_height" android:layout_marginTop="@dimen/notification_progress_margin_top" layout="@layout/notification_template_progress" /> - From 9863a144cf6000435744bc73877062d925321c26 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Mon, 26 Oct 2020 15:52:12 -0400 Subject: [PATCH 2/3] Respect the gravity of the NotificationTopLineView. Test: atest SystemUITests Test: manually tested within my branch with new templates Change-Id: I57a12287f1ce712914f985cc0de4df7613c18164 --- .../android/view/NotificationTopLineView.java | 74 ++++++++++++++++++- .../layout/notification_template_top_line.xml | 9 +-- 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/core/java/android/view/NotificationTopLineView.java b/core/java/android/view/NotificationTopLineView.java index 9443ccfc75534..69094b166fdb7 100644 --- a/core/java/android/view/NotificationTopLineView.java +++ b/core/java/android/view/NotificationTopLineView.java @@ -19,6 +19,7 @@ package android.view; import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Rect; import android.util.AttributeSet; import android.widget.RemoteViews; @@ -36,6 +37,7 @@ import java.util.List; */ @RemoteViews.RemoteView public class NotificationTopLineView extends ViewGroup { + private final int mGravityY; private final int mChildMinWidth; private final int mContentEndMargin; private View mAppName; @@ -48,6 +50,9 @@ public class NotificationTopLineView extends ViewGroup { private int mHeaderTextMarginEnd; private List mIconsAtEnd; + private int mMaxAscent; + private int mMaxDescent; + public NotificationTopLineView(Context context) { this(context, null); } @@ -67,6 +72,20 @@ public class NotificationTopLineView extends ViewGroup { Resources res = getResources(); mChildMinWidth = res.getDimensionPixelSize(R.dimen.notification_header_shrink_min_width); mContentEndMargin = res.getDimensionPixelSize(R.dimen.notification_content_margin_end); + + // NOTE: Implementation only supports TOP, BOTTOM, and CENTER_VERTICAL gravities, + // with CENTER_VERTICAL being the default. + int[] attrIds = {android.R.attr.gravity}; + TypedArray ta = context.obtainStyledAttributes(attrs, attrIds, defStyleAttr, defStyleRes); + int gravity = ta.getInt(0, 0); + ta.recycle(); + if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) { + mGravityY = Gravity.BOTTOM; + } else if ((gravity & Gravity.TOP) == Gravity.TOP) { + mGravityY = Gravity.TOP; + } else { + mGravityY = Gravity.CENTER_VERTICAL; + } } @Override @@ -90,6 +109,8 @@ public class NotificationTopLineView extends ViewGroup { MeasureSpec.AT_MOST); int totalWidth = getPaddingStart(); int iconWidth = getPaddingEnd(); + mMaxAscent = -1; + mMaxDescent = -1; for (int i = 0; i < getChildCount(); i++) { final View child = getChildAt(i); if (child.getVisibility() == GONE) { @@ -108,6 +129,11 @@ public class NotificationTopLineView extends ViewGroup { } else { totalWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth(); } + int childBaseline = child.getBaseline(); + if (childBaseline != -1) { + mMaxAscent = Math.max(mMaxAscent, childBaseline); + mMaxDescent = Math.max(mMaxDescent, child.getMeasuredHeight() - childBaseline); + } } // Ensure that there is at least enough space for the icons @@ -146,7 +172,13 @@ public class NotificationTopLineView extends ViewGroup { int left = getPaddingStart(); int end = getMeasuredWidth(); int childCount = getChildCount(); - int ownHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); + int ownHeight = b - t; + int childSpace = ownHeight - mPaddingTop - mPaddingBottom; + + // Instead of centering the baseline, pick a baseline that centers views which align to it. + // Only used when mGravityY is CENTER_VERTICAL + int baselineY = mPaddingTop + ((childSpace - (mMaxAscent + mMaxDescent)) / 2) + mMaxAscent; + for (int i = 0; i < childCount; i++) { View child = getChildAt(i); if (child.getVisibility() == GONE) { @@ -156,8 +188,42 @@ public class NotificationTopLineView extends ViewGroup { MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams(); int layoutLeft; int layoutRight; - int top = (int) (getPaddingTop() + (ownHeight - childHeight) / 2.0f); - int bottom = top + childHeight; + + // Calculate vertical alignment of the views, accounting for the view baselines + int childTop; + int childBaseline = child.getBaseline(); + switch (mGravityY) { + case Gravity.TOP: + childTop = mPaddingTop + params.topMargin; + if (childBaseline != -1) { + childTop += mMaxAscent - childBaseline; + } + break; + case Gravity.CENTER_VERTICAL: + if (childBaseline != -1) { + // Align baselines vertically only if the child is smaller than us + if (childSpace - childHeight > 0) { + childTop = baselineY - childBaseline; + } else { + childTop = mPaddingTop + (childSpace - childHeight) / 2; + } + } else { + childTop = mPaddingTop + ((childSpace - childHeight) / 2) + + params.topMargin - params.bottomMargin; + } + break; + case Gravity.BOTTOM: + int childBottom = ownHeight - mPaddingBottom; + childTop = childBottom - childHeight - params.bottomMargin; + if (childBaseline != -1) { + int descent = childHeight - childBaseline; + childTop -= (mMaxDescent - descent); + } + break; + default: + childTop = mPaddingTop; + } + // Icons that should go at the end if (mIconsAtEnd.contains(child)) { if (end == getMeasuredWidth()) { @@ -179,7 +245,7 @@ public class NotificationTopLineView extends ViewGroup { layoutLeft = getWidth() - layoutRight; layoutRight = getWidth() - ltrLeft; } - child.layout(layoutLeft, top, layoutRight, bottom); + child.layout(layoutLeft, childTop, layoutRight, childTop + childHeight); } updateTouchListener(); } diff --git a/core/res/res/layout/notification_template_top_line.xml b/core/res/res/layout/notification_template_top_line.xml index 27fab859a0456..0786e138559f4 100644 --- a/core/res/res/layout/notification_template_top_line.xml +++ b/core/res/res/layout/notification_template_top_line.xml @@ -102,9 +102,8 @@ android:id="@+id/alerted_icon" android:layout_width="@dimen/notification_alerted_size" android:layout_height="@dimen/notification_alerted_size" - android:layout_gravity="center" android:layout_marginStart="4dp" - android:paddingTop="1dp" + android:baseline="10dp" android:scaleType="fitCenter" android:visibility="gone" android:contentDescription="@string/notification_alerted_content_description" @@ -116,8 +115,7 @@ android:layout_height="@dimen/notification_feedback_size" android:layout_marginStart="6dp" android:layout_marginEnd="6dp" - android:paddingTop="2dp" - android:layout_gravity="center" + android:baseline="10dp" android:scaleType="fitCenter" android:src="@drawable/ic_feedback_indicator" android:background="?android:selectableItemBackgroundBorderless" @@ -128,9 +126,8 @@ android:id="@+id/profile_badge" android:layout_width="@dimen/notification_badge_size" android:layout_height="@dimen/notification_badge_size" - android:layout_gravity="center" android:layout_marginStart="4dp" - android:paddingTop="1dp" + android:baseline="10dp" android:scaleType="fitCenter" android:visibility="gone" android:contentDescription="@string/notification_work_profile_content_description" From 7995e6d7b51337f5fc973be47b4edfcfc602fb20 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Tue, 27 Oct 2020 10:50:14 -0400 Subject: [PATCH 3/3] NotificationTopLineView supports layout_height="wrap_content" Test: atest SystemUITests Test: manually tested within my branch which does this Change-Id: I78412489be7723697d8dc3106dbb4d67fd72a3a0 --- core/java/android/view/NotificationTopLineView.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/java/android/view/NotificationTopLineView.java b/core/java/android/view/NotificationTopLineView.java index 69094b166fdb7..24748222b3af7 100644 --- a/core/java/android/view/NotificationTopLineView.java +++ b/core/java/android/view/NotificationTopLineView.java @@ -103,12 +103,14 @@ public class NotificationTopLineView extends ViewGroup { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int givenWidth = MeasureSpec.getSize(widthMeasureSpec); final int givenHeight = MeasureSpec.getSize(heightMeasureSpec); + final boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST; int wrapContentWidthSpec = MeasureSpec.makeMeasureSpec(givenWidth, MeasureSpec.AT_MOST); int wrapContentHeightSpec = MeasureSpec.makeMeasureSpec(givenHeight, MeasureSpec.AT_MOST); int totalWidth = getPaddingStart(); int iconWidth = getPaddingEnd(); + int maxChildHeight = -1; mMaxAscent = -1; mMaxDescent = -1; for (int i = 0; i < getChildCount(); i++) { @@ -130,10 +132,12 @@ public class NotificationTopLineView extends ViewGroup { totalWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth(); } int childBaseline = child.getBaseline(); + int childHeight = child.getMeasuredHeight(); if (childBaseline != -1) { mMaxAscent = Math.max(mMaxAscent, childBaseline); - mMaxDescent = Math.max(mMaxDescent, child.getMeasuredHeight() - childBaseline); + mMaxDescent = Math.max(mMaxDescent, childHeight - childBaseline); } + maxChildHeight = Math.max(maxChildHeight, childHeight); } // Ensure that there is at least enough space for the icons @@ -151,7 +155,7 @@ public class NotificationTopLineView extends ViewGroup { shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mSecondaryHeaderText, 0); } - setMeasuredDimension(givenWidth, givenHeight); + setMeasuredDimension(givenWidth, wrapHeight ? maxChildHeight : givenHeight); } private int shrinkViewForOverflow(int heightSpec, int overFlow, View targetView,