Merge changes I11400a55,I49461363,Ia18b2dc3,I8c554755 into sc-dev

* changes:
  Simplify SmartReplyView padding layout logic
  Smart action buttons now have 8dp corner radius
  Fix measure logic so that priority children can have more than 1/N space.
  Update the style of emphasized notification actions.
This commit is contained in:
Jeff DeCew
2021-05-11 22:35:37 +00:00
committed by Android (Google) Code Review
13 changed files with 116 additions and 209 deletions

View File

@@ -5662,11 +5662,6 @@ public class Notification implements Parcelable
R.dimen.call_notification_collapsible_indent);
}
big.setBoolean(R.id.actions, "setEmphasizedMode", emphazisedMode);
if (p.mCallStyleActions) {
// Use "wrap_content" (unlike normal emphasized mode) and allow prioritizing the
// required actions (Answer, Decline, and Hang Up).
big.setBoolean(R.id.actions, "setPrioritizedWrapMode", true);
}
if (numActions > 0 && !p.mHideActions) {
big.setViewVisibility(R.id.actions_container, View.VISIBLE);
big.setViewVisibility(R.id.actions, View.VISIBLE);
@@ -5683,7 +5678,7 @@ public class Notification implements Parcelable
// Clear the drawable
button.setInt(R.id.action0, "setBackgroundResource", 0);
}
if (p.mCallStyleActions && i > 0) {
if (emphazisedMode && i > 0) {
// Clear start margin from non-first buttons to reduce the gap between them.
// (8dp remaining gap is from all buttons' standard 4dp inset).
button.setViewLayoutMarginDimen(R.id.action0, RemoteViews.MARGIN_START, 0);
@@ -6103,26 +6098,21 @@ public class Notification implements Parcelable
// change the background bgColor
CharSequence title = action.title;
ColorStateList[] outResultColor = new ColorStateList[1];
int background = getBackgroundColor(p);
int background = getSecondaryAccentColor(p);
if (isLegacy()) {
title = ContrastColorUtil.clearColorSpans(title);
} else {
title = ensureColorSpanContrast(title, background, outResultColor);
}
button.setTextViewText(R.id.action0, processTextSpans(title));
final int textColor;
boolean hasColorOverride = outResultColor[0] != null;
if (hasColorOverride) {
// There's a span spanning the full text, let's take it and use it as the
// background color
background = outResultColor[0].getDefaultColor();
textColor = ContrastColorUtil.resolvePrimaryColor(mContext,
background, mInNightMode);
} else if (mTintActionButtons && !mInNightMode && !isBackgroundColorized(p)) {
textColor = getAccentColor(p);
} else {
textColor = getPrimaryTextColor(p);
}
final int textColor = ContrastColorUtil.resolvePrimaryColor(mContext,
background, mInNightMode);
button.setTextColor(R.id.action0, textColor);
// We only want about 20% alpha for the ripple
final int rippleColor = (textColor & 0x00ffffff) | 0x33000000;
@@ -6130,11 +6120,10 @@ public class Notification implements Parcelable
ColorStateList.valueOf(rippleColor));
button.setColorStateList(R.id.action0, "setButtonBackground",
ColorStateList.valueOf(background));
button.setBoolean(R.id.action0, "setHasStroke", !hasColorOverride);
if (p.mCallStyleActions) {
button.setImageViewIcon(R.id.action0, action.getIcon());
boolean priority = action.getExtras().getBoolean(CallStyle.KEY_ACTION_PRIORITY);
button.setBoolean(R.id.action0, "setWrapModePriority", priority);
button.setBoolean(R.id.action0, "setIsPriority", priority);
int minWidthDimen =
priority ? R.dimen.call_notification_system_action_min_width : 0;
button.setIntDimen(R.id.action0, "setMinimumWidth", minWidthDimen);
@@ -6319,6 +6308,22 @@ public class Notification implements Parcelable
return getContrastColor(p);
}
/**
* Gets the secondary accent color for colored UI elements. If we're tinting with the theme
* accent, this is the theme accent color, otherwise this would be identical to
* {@link #getSmallIconColor(StandardTemplateParams)}.
*/
private @ColorInt int getSecondaryAccentColor(StandardTemplateParams p) {
if (isBackgroundColorized(p)) {
return getSecondaryTextColor(p);
}
int color = obtainThemeColor(R.attr.colorAccentSecondary, COLOR_INVALID);
if (color != COLOR_INVALID) {
return color;
}
return getContrastColor(p);
}
/**
* Gets the "surface protection" color from the theme, or a variant of the normal background
* color when colorized, or when not using theme color tints.

View File

@@ -27,9 +27,7 @@ import android.graphics.drawable.Icon;
import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.view.RemotableViewMethod;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import com.android.internal.R;
@@ -42,8 +40,6 @@ import com.android.internal.R;
@RemoteViews.RemoteView
public class EmphasizedNotificationButton extends Button {
private final RippleDrawable mRipple;
private final int mStrokeWidth;
private final int mStrokeColor;
private boolean mPriority;
public EmphasizedNotificationButton(Context context) {
@@ -63,9 +59,6 @@ public class EmphasizedNotificationButton extends Button {
super(context, attrs, defStyleAttr, defStyleRes);
DrawableWrapper background = (DrawableWrapper) getBackground().mutate();
mRipple = (RippleDrawable) background.getDrawable();
mStrokeWidth = getResources().getDimensionPixelSize(
com.android.internal.R.dimen.emphasized_button_stroke_width);
mStrokeColor = getContext().getColor(com.android.internal.R.color.material_grey_300);
mRipple.mutate();
}
@@ -82,13 +75,6 @@ public class EmphasizedNotificationButton extends Button {
invalidate();
}
@RemotableViewMethod
public void setHasStroke(boolean hasStroke) {
GradientDrawable inner = (GradientDrawable) mRipple.getDrawable(0);
inner.setStroke(hasStroke ? mStrokeWidth : 0, mStrokeColor);
invalidate();
}
/**
* Sets an image icon which will have its size constrained and will be set to the same color as
* the text. Must be called after {@link #setTextColor(int)} for the latter to work.
@@ -121,18 +107,13 @@ public class EmphasizedNotificationButton extends Button {
}
/**
* Changes the LayoutParams.width to WRAP_CONTENT, with the argument representing if this view
* is a priority over its peers (which affects weight).
* Sets whether this view is a priority over its peers (which affects width).
* Specifically, this is used by {@link NotificationActionListLayout} to give this view width
* priority ahead of user-defined buttons when allocating horizontal space.
*/
@RemotableViewMethod
public void setWrapModePriority(boolean priority) {
public void setIsPriority(boolean priority) {
mPriority = priority;
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
if (layoutParams instanceof LinearLayout.LayoutParams) {
((LinearLayout.LayoutParams) layoutParams).weight = 0;
}
setLayoutParams(layoutParams);
}
/**

View File

@@ -17,11 +17,11 @@
package com.android.internal.widget;
import android.annotation.DimenRes;
import android.app.Notification;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.Gravity;
import android.view.RemotableViewMethod;
import android.view.View;
@@ -43,10 +43,9 @@ public class NotificationActionListLayout extends LinearLayout {
private final int mGravity;
private int mTotalWidth = 0;
private int mExtraStartPadding = 0;
private ArrayList<Pair<Integer, TextView>> mMeasureOrderTextViews = new ArrayList<>();
private ArrayList<TextViewInfo> mMeasureOrderTextViews = new ArrayList<>();
private ArrayList<View> mMeasureOrderOther = new ArrayList<>();
private boolean mEmphasizedMode;
private boolean mPrioritizedWrapMode;
private int mDefaultPaddingBottom;
private int mDefaultPaddingTop;
private int mEmphasizedHeight;
@@ -70,16 +69,18 @@ public class NotificationActionListLayout extends LinearLayout {
ta.recycle();
}
private static boolean isPriority(View actionView) {
return actionView instanceof EmphasizedNotificationButton
&& ((EmphasizedNotificationButton) actionView).isPriority();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mEmphasizedMode && !mPrioritizedWrapMode) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
final int N = getChildCount();
int textViews = 0;
int otherViews = 0;
int notGoneChildren = 0;
int priorityChildren = 0;
for (int i = 0; i < N; i++) {
View c = getChildAt(i);
@@ -90,6 +91,9 @@ public class NotificationActionListLayout extends LinearLayout {
}
if (c.getVisibility() != GONE) {
notGoneChildren++;
if (isPriority(c)) {
priorityChildren++;
}
}
}
@@ -103,9 +107,9 @@ public class NotificationActionListLayout extends LinearLayout {
if (!needRebuild) {
final int size = mMeasureOrderTextViews.size();
for (int i = 0; i < size; i++) {
Pair<Integer, TextView> pair = mMeasureOrderTextViews.get(i);
if (pair.first != pair.second.getText().length()) {
if (mMeasureOrderTextViews.get(i).needsRebuild()) {
needRebuild = true;
break;
}
}
}
@@ -122,14 +126,19 @@ public class NotificationActionListLayout extends LinearLayout {
int usedWidth = 0;
int measuredChildren = 0;
int measuredPriorityChildren = 0;
for (int i = 0; i < N; i++) {
// Measure shortest children first. To avoid measuring twice, we approximate by looking
// at the text length.
View c;
final boolean isPriority;
final View c;
if (i < otherSize) {
c = mMeasureOrderOther.get(i);
isPriority = false;
} else {
c = mMeasureOrderTextViews.get(i - otherSize).second;
TextViewInfo info = mMeasureOrderTextViews.get(i - otherSize);
c = info.mTextView;
isPriority = info.mIsPriority;
}
if (c.getVisibility() == GONE) {
continue;
@@ -143,7 +152,18 @@ public class NotificationActionListLayout extends LinearLayout {
// measure in the order of (approx.) size, a large view can still take more than its
// share if the others are small.
int availableWidth = innerWidth - usedWidth;
int maxWidthForChild = availableWidth / (notGoneChildren - measuredChildren);
int unmeasuredChildren = notGoneChildren - measuredChildren;
int maxWidthForChild = availableWidth / unmeasuredChildren;
if (isPriority) {
// Priority children get a larger maximum share of the total space:
// maximum priority share = (nPriority + 1) / (MAX + 1)
int unmeasuredPriorityChildren = priorityChildren - measuredPriorityChildren;
int unmeasuredOtherChildren = unmeasuredChildren - unmeasuredPriorityChildren;
int widthReservedForOtherChildren = innerWidth * unmeasuredOtherChildren
/ (Notification.MAX_ACTION_BUTTONS + 1);
int widthAvailableForPriority = availableWidth - widthReservedForOtherChildren;
maxWidthForChild = widthAvailableForPriority / unmeasuredPriorityChildren;
}
usedWidthForChild = innerWidth - maxWidthForChild;
}
@@ -153,6 +173,9 @@ public class NotificationActionListLayout extends LinearLayout {
usedWidth += c.getMeasuredWidth() + lp.rightMargin + lp.leftMargin;
measuredChildren++;
if (isPriority) {
measuredPriorityChildren++;
}
}
int collapsibleIndent = mCollapsibleIndentDimen == 0 ? 0
@@ -175,13 +198,8 @@ public class NotificationActionListLayout extends LinearLayout {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View c = getChildAt(i);
if (c instanceof EmphasizedNotificationButton
&& ((EmphasizedNotificationButton) c).isPriority()) {
// add with 0 length to ensure that this view is measured before others.
mMeasureOrderTextViews.add(Pair.create(0, (TextView) c));
} else if (c instanceof TextView && ((TextView) c).getText().length() > 0) {
mMeasureOrderTextViews.add(Pair.create(((TextView) c).getText().length(),
(TextView)c));
if (c instanceof TextView && ((TextView) c).getText().length() > 0) {
mMeasureOrderTextViews.add(new TextViewInfo((TextView) c));
} else {
mMeasureOrderOther.add(c);
}
@@ -213,10 +231,6 @@ public class NotificationActionListLayout extends LinearLayout {
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (mEmphasizedMode && !mPrioritizedWrapMode) {
super.onLayout(changed, left, top, right, bottom);
return;
}
final boolean isLayoutRtl = isLayoutRtl();
final int paddingTop = mPaddingTop;
final boolean centerAligned = (mGravity & Gravity.CENTER_HORIZONTAL) != 0;
@@ -292,16 +306,6 @@ public class NotificationActionListLayout extends LinearLayout {
com.android.internal.R.dimen.notification_action_list_height);
}
/**
* When used with emphasizedMode, changes the button sizing behavior to prioritize certain
* buttons (which are system generated) to not scrunch, and leave the remaining space for
* custom actions.
*/
@RemotableViewMethod
public void setPrioritizedWrapMode(boolean prioritizedWrapMode) {
mPrioritizedWrapMode = prioritizedWrapMode;
}
/**
* When buttons are in wrap mode, this is a padding that will be applied at the start of the
* layout of the actions, but only when those actions would fit with the entire padding
@@ -353,6 +357,28 @@ public class NotificationActionListLayout extends LinearLayout {
return 0;
}
public static final Comparator<Pair<Integer, TextView>> MEASURE_ORDER_COMPARATOR
= (a, b) -> a.first.compareTo(b.first);
public static final Comparator<TextViewInfo> MEASURE_ORDER_COMPARATOR = (a, b) -> {
int priorityComparison = -Boolean.compare(a.mIsPriority, b.mIsPriority);
return priorityComparison != 0
? priorityComparison
: Integer.compare(a.mTextLength, b.mTextLength);
};
private static final class TextViewInfo {
final boolean mIsPriority;
final int mTextLength;
final TextView mTextView;
TextViewInfo(TextView textView) {
this.mIsPriority = isPriority(textView);
this.mTextLength = textView.getText().length();
this.mTextView = textView;
}
boolean needsRebuild() {
return mTextView.getText().length() != mTextLength
|| isPriority(mTextView) != mIsPriority;
}
}
}

View File

@@ -24,13 +24,11 @@
<item>
<shape android:shape="rectangle">
<corners android:radius="@dimen/notification_action_button_radius" />
<padding android:left="@dimen/button_padding_horizontal_material"
<padding android:left="12dp"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:right="12dp"
android:bottom="@dimen/button_padding_vertical_material" />
<solid android:color="@color/white" />
<stroke android:width="@dimen/emphasized_button_stroke_width"
android:color="@color/material_grey_300"/>
</shape>
</item>
</ripple>

View File

@@ -18,10 +18,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/NotificationEmphasizedAction"
android:id="@+id/action0"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:drawablePadding="6dp"
android:gravity="center"
android:textColor="@color/notification_default_color"

View File

@@ -224,14 +224,14 @@
<!-- The margin on the end of the top-line content views (accommodates the expander) -->
<dimen name="notification_heading_margin_end">56dp</dimen>
<!-- The height of the notification action list -->
<!-- The total height of the notification action list -->
<dimen name="notification_action_list_height">60dp</dimen>
<!-- The margin of the notification action list at the top -->
<dimen name="notification_action_list_margin_top">0dp</dimen>
<!-- The height of the notification action list -->
<dimen name="notification_action_emphasized_height">48dp</dimen>
<!-- The visual height of the emphasized notification action -->
<dimen name="notification_action_emphasized_height">36dp</dimen>
<!-- The padding of the actions in non-conversation layout. For conversations, the analogous
value is calculated in ConversationLayout#updateActionListPadding() -->
@@ -252,7 +252,7 @@
<dimen name="notification_actions_icon_drawable_size">20dp</dimen>
<!-- The corner radius if the emphasized action buttons in a notification -->
<dimen name="notification_action_button_radius">8dp</dimen>
<dimen name="notification_action_button_radius">18dp</dimen>
<!-- Size of the stroke with for the emphasized notification button style -->
<dimen name="emphasized_button_stroke_width">1dp</dimen>

View File

@@ -29,6 +29,8 @@
android:textSize="@dimen/smart_reply_button_font_size"
android:lineSpacingExtra="@dimen/smart_reply_button_line_spacing_extra"
android:textColor="@color/smart_reply_button_text"
android:paddingLeft="@dimen/smart_reply_button_action_padding_left"
android:paddingRight="@dimen/smart_reply_button_padding_horizontal"
android:drawablePadding="@dimen/smart_action_button_icon_padding"
android:textStyle="normal"
android:ellipsize="none"/>

View File

@@ -31,5 +31,7 @@
android:textSize="@dimen/smart_reply_button_font_size"
android:lineSpacingExtra="@dimen/smart_reply_button_line_spacing_extra"
android:textColor="@color/smart_reply_button_text"
android:paddingLeft="@dimen/smart_reply_button_padding_horizontal"
android:paddingRight="@dimen/smart_reply_button_padding_horizontal"
android:textStyle="normal"
android:ellipsize="none"/>

View File

@@ -24,8 +24,6 @@
android:layout_height="wrap_content"
android:layout_width="wrap_content"
systemui:spacing="@dimen/smart_reply_button_spacing"
systemui:singleLineButtonPaddingHorizontal="@dimen/smart_reply_button_padding_horizontal_single_line"
systemui:doubleLineButtonPaddingHorizontal="@dimen/smart_reply_button_padding_horizontal_double_line"
systemui:buttonStrokeWidth="@dimen/smart_reply_button_stroke_width">
<!-- smart_reply_button(s) will be added here. -->
</com.android.systemui.statusbar.policy.SmartReplyView>

View File

@@ -131,8 +131,6 @@
<declare-styleable name="SmartReplyView">
<attr name="spacing" format="dimension" />
<attr name="singleLineButtonPaddingHorizontal" format="dimension" />
<attr name="doubleLineButtonPaddingHorizontal" format="dimension" />
<attr name="buttonStrokeWidth" format="dimension" />
</declare-styleable>

View File

@@ -1147,15 +1147,14 @@
<!-- Smart reply button. Total height 48dp, visible height 32dp. -->
<dimen name="smart_reply_button_spacing">8dp</dimen>
<dimen name="smart_reply_button_padding_vertical">14dp</dimen>
<!-- Note: The following two paddings need to be different until b/78876518 is fixed. -->
<dimen name="smart_reply_button_padding_horizontal_single_line">20dp</dimen>
<dimen name="smart_reply_button_padding_horizontal_double_line">19dp</dimen>
<dimen name="smart_reply_button_padding_horizontal">16dp</dimen>
<dimen name="smart_reply_button_action_padding_left">8dp</dimen>
<dimen name="smart_reply_button_min_height">48dp</dimen>
<dimen name="smart_reply_button_stroke_width">1dp</dimen>
<dimen name="smart_reply_button_font_size">14sp</dimen>
<dimen name="smart_reply_button_line_spacing_extra">6sp</dimen> <!-- Total line height 20sp. -->
<!-- Corner radius = half of min_height to create rounded sides. -->
<dimen name="smart_reply_button_corner_radius">24dp</dimen>
<dimen name="smart_reply_button_corner_radius">8dp</dimen>
<dimen name="smart_action_button_icon_size">18dp</dimen>
<dimen name="smart_action_button_icon_padding">8dp</dimen>

View File

@@ -23,6 +23,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ContrastColorUtil;
@@ -58,15 +59,6 @@ public class SmartReplyView extends ViewGroup {
/** Spacing to be applied between views. */
private final int mSpacing;
/** Horizontal padding of smart reply buttons if all of them use only one line of text. */
private final int mSingleLineButtonPaddingHorizontal;
/** Horizontal padding of smart reply buttons if at least one of them uses two lines of text. */
private final int mDoubleLineButtonPaddingHorizontal;
/** Increase in width of a smart reply button as a result of using two lines instead of one. */
private final int mSingleToDoubleLineButtonWidthIncrease;
private final BreakIterator mBreakIterator;
private PriorityQueue<Button> mCandidateButtonQueueForSqueezing;
@@ -114,8 +106,6 @@ public class SmartReplyView extends ViewGroup {
mDefaultBackgroundColor);
int spacing = 0;
int singleLineButtonPaddingHorizontal = 0;
int doubleLineButtonPaddingHorizontal = 0;
int strokeWidth = 0;
final TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.SmartReplyView,
@@ -125,10 +115,6 @@ public class SmartReplyView extends ViewGroup {
int attr = arr.getIndex(i);
if (attr == R.styleable.SmartReplyView_spacing) {
spacing = arr.getDimensionPixelSize(i, 0);
} else if (attr == R.styleable.SmartReplyView_singleLineButtonPaddingHorizontal) {
singleLineButtonPaddingHorizontal = arr.getDimensionPixelSize(i, 0);
} else if (attr == R.styleable.SmartReplyView_doubleLineButtonPaddingHorizontal) {
doubleLineButtonPaddingHorizontal = arr.getDimensionPixelSize(i, 0);
} else if (attr == R.styleable.SmartReplyView_buttonStrokeWidth) {
strokeWidth = arr.getDimensionPixelSize(i, 0);
}
@@ -137,10 +123,6 @@ public class SmartReplyView extends ViewGroup {
mStrokeWidth = strokeWidth;
mSpacing = spacing;
mSingleLineButtonPaddingHorizontal = singleLineButtonPaddingHorizontal;
mDoubleLineButtonPaddingHorizontal = doubleLineButtonPaddingHorizontal;
mSingleToDoubleLineButtonWidthIncrease =
2 * (doubleLineButtonPaddingHorizontal - singleLineButtonPaddingHorizontal);
mBreakIterator = BreakIterator.getLineInstance();
@@ -222,6 +204,12 @@ public class SmartReplyView extends ViewGroup {
return new LayoutParams(params.width, params.height);
}
private void clearLayoutLineCount(View view) {
if (view instanceof TextView) {
((TextView) view).nullLayouts();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int targetWidth = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED
@@ -237,8 +225,7 @@ public class SmartReplyView extends ViewGroup {
SmartSuggestionMeasures accumulatedMeasures = new SmartSuggestionMeasures(
mPaddingLeft + mPaddingRight,
0 /* maxChildHeight */,
mSingleLineButtonPaddingHorizontal);
0 /* maxChildHeight */);
int displayedChildCount = 0;
// Set up a list of suggestions where actions come before replies. Note that the Buttons
@@ -268,8 +255,7 @@ public class SmartReplyView extends ViewGroup {
continue;
}
child.setPadding(accumulatedMeasures.mButtonPaddingHorizontal, child.getPaddingTop(),
accumulatedMeasures.mButtonPaddingHorizontal, child.getPaddingBottom());
clearLayoutLineCount(child);
child.measure(MEASURE_SPEC_ANY_LENGTH, heightMeasureSpec);
coveredSuggestions.add(child);
@@ -299,18 +285,6 @@ public class SmartReplyView extends ViewGroup {
accumulatedMeasures.mMaxChildHeight =
Math.max(accumulatedMeasures.mMaxChildHeight, childHeight);
// Do we need to increase the number of lines in smart reply buttons to two?
final boolean increaseToTwoLines =
(accumulatedMeasures.mButtonPaddingHorizontal
== mSingleLineButtonPaddingHorizontal)
&& (lineCount == 2 || accumulatedMeasures.mMeasuredWidth > targetWidth);
if (increaseToTwoLines) {
accumulatedMeasures.mMeasuredWidth +=
(displayedChildCount + 1) * mSingleToDoubleLineButtonWidthIncrease;
accumulatedMeasures.mButtonPaddingHorizontal =
mDoubleLineButtonPaddingHorizontal;
}
// If the last button doesn't fit into the remaining width, try squeezing preceding
// smart reply buttons.
if (accumulatedMeasures.mMeasuredWidth > targetWidth) {
@@ -372,18 +346,11 @@ public class SmartReplyView extends ViewGroup {
mCandidateButtonQueueForSqueezing.clear();
// Finally, we need to re-measure some buttons.
remeasureButtonsIfNecessary(accumulatedMeasures.mButtonPaddingHorizontal,
accumulatedMeasures.mMaxChildHeight);
remeasureButtonsIfNecessary(accumulatedMeasures.mMaxChildHeight);
int buttonHeight = Math.max(getSuggestedMinimumHeight(), mPaddingTop
+ accumulatedMeasures.mMaxChildHeight + mPaddingBottom);
// Set the corner radius to half the button height to make the side of the buttons look like
// a semicircle.
for (View smartSuggestionButton : smartSuggestions) {
setCornerRadius((Button) smartSuggestionButton, ((float) buttonHeight) / 2);
}
setMeasuredDimension(
resolveSize(Math.max(getSuggestedMinimumWidth(),
accumulatedMeasures.mMeasuredWidth),
@@ -411,18 +378,14 @@ public class SmartReplyView extends ViewGroup {
private static class SmartSuggestionMeasures {
int mMeasuredWidth = -1;
int mMaxChildHeight = -1;
int mButtonPaddingHorizontal = -1;
SmartSuggestionMeasures(int measuredWidth, int maxChildHeight,
int buttonPaddingHorizontal) {
SmartSuggestionMeasures(int measuredWidth, int maxChildHeight) {
this.mMeasuredWidth = measuredWidth;
this.mMaxChildHeight = maxChildHeight;
this.mButtonPaddingHorizontal = buttonPaddingHorizontal;
}
public SmartSuggestionMeasures clone() {
return new SmartSuggestionMeasures(
mMeasuredWidth, mMaxChildHeight, mButtonPaddingHorizontal);
return new SmartSuggestionMeasures(mMeasuredWidth, mMaxChildHeight);
}
}
@@ -553,17 +516,11 @@ public class SmartReplyView extends ViewGroup {
private int squeezeButtonToTextWidth(Button button, int heightMeasureSpec, int textWidth) {
int oldWidth = button.getMeasuredWidth();
if (button.getPaddingLeft() != mDoubleLineButtonPaddingHorizontal) {
// Correct for the fact that the button was laid out with single-line horizontal
// padding.
oldWidth += mSingleToDoubleLineButtonWidthIncrease;
}
// Re-measure the squeezed smart reply button.
button.setPadding(mDoubleLineButtonPaddingHorizontal, button.getPaddingTop(),
mDoubleLineButtonPaddingHorizontal, button.getPaddingBottom());
clearLayoutLineCount(button);
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(
2 * mDoubleLineButtonPaddingHorizontal + textWidth
button.getPaddingLeft() + button.getPaddingRight() + textWidth
+ getLeftCompoundDrawableWidthWithPadding(button), MeasureSpec.AT_MOST);
button.measure(widthMeasureSpec, heightMeasureSpec);
@@ -579,8 +536,7 @@ public class SmartReplyView extends ViewGroup {
}
}
private void remeasureButtonsIfNecessary(
int buttonPaddingHorizontal, int maxChildHeight) {
private void remeasureButtonsIfNecessary(int maxChildHeight) {
final int maxChildHeightMeasure =
MeasureSpec.makeMeasureSpec(maxChildHeight, MeasureSpec.EXACTLY);
@@ -602,24 +558,7 @@ public class SmartReplyView extends ViewGroup {
newWidth = Integer.MAX_VALUE;
}
// Re-measure reason 2: The button's horizontal padding is incorrect (because it was
// measured with the wrong number of lines).
if (child.getPaddingLeft() != buttonPaddingHorizontal) {
requiresNewMeasure = true;
if (newWidth != Integer.MAX_VALUE) {
if (buttonPaddingHorizontal == mSingleLineButtonPaddingHorizontal) {
// Change padding (2->1 line).
newWidth -= mSingleToDoubleLineButtonWidthIncrease;
} else {
// Change padding (1->2 lines).
newWidth += mSingleToDoubleLineButtonWidthIncrease;
}
}
child.setPadding(buttonPaddingHorizontal, child.getPaddingTop(),
buttonPaddingHorizontal, child.getPaddingBottom());
}
// Re-measure reason 3: The button's height is less than the max height of all buttons
// Re-measure reason 2: The button's height is less than the max height of all buttons
// (all should have the same height).
if (child.getMeasuredHeight() != maxChildHeight) {
requiresNewMeasure = true;
@@ -725,23 +664,6 @@ public class SmartReplyView extends ViewGroup {
button.setTextColor(mCurrentTextColor);
}
private void setCornerRadius(Button button, float radius) {
Drawable drawable = button.getBackground();
if (drawable instanceof RippleDrawable) {
// Mutate in case other notifications are using this drawable.
drawable = drawable.mutate();
RippleDrawable ripple = (RippleDrawable) drawable;
Drawable inset = ripple.getDrawable(0);
if (inset instanceof InsetDrawable) {
Drawable background = ((InsetDrawable) inset).getDrawable();
if (background instanceof GradientDrawable) {
GradientDrawable gradientDrawable = (GradientDrawable) background;
gradientDrawable.setCornerRadius(radius);
}
}
}
}
enum SmartButtonType {
REPLY,
ACTION

View File

@@ -20,7 +20,6 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
@@ -100,8 +99,6 @@ public class SmartReplyViewTest extends SysuiTestCase {
private Icon mActionIcon;
private int mSingleLinePaddingHorizontal;
private int mDoubleLinePaddingHorizontal;
private int mSpacing;
private NotificationEntry mEntry;
@@ -141,10 +138,6 @@ public class SmartReplyViewTest extends SysuiTestCase {
mView = SmartReplyView.inflate(mContext, mConstants);
final Resources res = mContext.getResources();
mSingleLinePaddingHorizontal = res.getDimensionPixelSize(
R.dimen.smart_reply_button_padding_horizontal_single_line);
mDoubleLinePaddingHorizontal = res.getDimensionPixelSize(
R.dimen.smart_reply_button_padding_horizontal_double_line);
mSpacing = res.getDimensionPixelSize(R.dimen.smart_reply_button_spacing);
mNotification = new Notification.Builder(mContext, "")
@@ -588,18 +581,6 @@ public class SmartReplyViewTest extends SysuiTestCase {
layout.setBaselineAligned(false);
final boolean isRtl = mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
final int paddingHorizontal;
switch (lineCount) {
case 1:
paddingHorizontal = mSingleLinePaddingHorizontal;
break;
case 2:
paddingHorizontal = mDoubleLinePaddingHorizontal;
break;
default:
fail("Invalid line count " + lineCount);
return null;
}
// Add smart replies
Button previous = null;
@@ -617,8 +598,6 @@ public class SmartReplyViewTest extends SysuiTestCase {
true /* delayOnClickListener */))
.iterator()));
for (Button current : inflatedReplies) {
current.setPadding(paddingHorizontal, current.getPaddingTop(), paddingHorizontal,
current.getPaddingBottom());
if (previous != null) {
ViewGroup.MarginLayoutParams lp =
(ViewGroup.MarginLayoutParams) previous.getLayoutParams();
@@ -647,8 +626,6 @@ public class SmartReplyViewTest extends SysuiTestCase {
// Add smart actions
for (Button current : inflatedSmartActions) {
current.setPadding(paddingHorizontal, current.getPaddingTop(), paddingHorizontal,
current.getPaddingBottom());
if (previous != null) {
ViewGroup.MarginLayoutParams lp =
(ViewGroup.MarginLayoutParams) previous.getLayoutParams();