diff options
| -rw-r--r-- | core/java/com/android/internal/widget/NotificationActionListLayout.java | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/core/java/com/android/internal/widget/NotificationActionListLayout.java b/core/java/com/android/internal/widget/NotificationActionListLayout.java index ea7188840aa2..a4d6a6052117 100644 --- a/core/java/com/android/internal/widget/NotificationActionListLayout.java +++ b/core/java/com/android/internal/widget/NotificationActionListLayout.java @@ -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,7 +43,7 @@ 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 int mDefaultPaddingBottom; @@ -69,12 +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) { 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); @@ -85,6 +91,9 @@ public class NotificationActionListLayout extends LinearLayout { } if (c.getVisibility() != GONE) { notGoneChildren++; + if (isPriority(c)) { + priorityChildren++; + } } } @@ -98,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; } } } @@ -117,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; @@ -138,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; } @@ -148,6 +173,9 @@ public class NotificationActionListLayout extends LinearLayout { usedWidth += c.getMeasuredWidth() + lp.rightMargin + lp.leftMargin; measuredChildren++; + if (isPriority) { + measuredPriorityChildren++; + } } int collapsibleIndent = mCollapsibleIndentDimen == 0 ? 0 @@ -170,12 +198,8 @@ public class NotificationActionListLayout extends LinearLayout { final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View c = getChildAt(i); - if (isPriority(c)) { - // 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); } @@ -333,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; + } + } + } |