Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64aed1a2 authored by Selim Cinek's avatar Selim Cinek
Browse files

Improved collapsed messaging notifications

Previously the messaging layout was working on a fixed
Height, which didn't scale well as we were now using it
also in the collapsed version.
For big text notifications, the view would be
clipped ugly, since we were using a fixed number of
lines. Instead we're now calculating this dynamically.

Fixes: 35126759
Test: runtest systemui
Change-Id: Ie3736d807d7a162ee51ad65794bf2f1cfb2248be
parent 1b7ea181
Loading
Loading
Loading
Loading
+0 −13
Original line number Diff line number Diff line
@@ -4962,9 +4962,6 @@ public class Notification implements Parcelable
     */
    public static class BigTextStyle extends Style {

        private static final int MAX_LINES = 13;
        private static final int LINES_CONSUMED_BY_ACTIONS = 4;

        private CharSequence mBigText;

        public BigTextStyle() {
@@ -5070,18 +5067,8 @@ public class Notification implements Parcelable
            builder.setTextViewColorSecondary(contentView, R.id.big_text);
            contentView.setViewVisibility(R.id.big_text,
                    TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE);
            contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines(builder));
            contentView.setBoolean(R.id.big_text, "setHasImage", builder.mN.hasLargeIcon());
        }

        private static int calculateMaxLines(Builder builder) {
            int lineCount = MAX_LINES;
            boolean hasActions = builder.mActions.size() > 0;
            if (hasActions) {
                lineCount -= LINES_CONSUMED_BY_ACTIONS;
            }
            return lineCount;
        }
    }

    /**
+41 −2
Original line number Diff line number Diff line
@@ -42,6 +42,10 @@ public class ImageFloatingTextView extends TextView {

    /** Resolved layout direction */
    private int mResolvedDirection = LAYOUT_DIRECTION_UNDEFINED;
    private int mMaxLinesForHeight = -1;
    private boolean mFirstMeasure = true;
    private int mLayoutMaxLines = -1;
    private boolean mBlockLayouts;

    public ImageFloatingTextView(Context context) {
        this(context, null);
@@ -72,8 +76,15 @@ public class ImageFloatingTextView extends TextView {
                .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier())
                .setIncludePad(getIncludeFontPadding())
                .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
                .setMaxLines(getMaxLines() >= 0 ? getMaxLines() : Integer.MAX_VALUE);
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
        int maxLines;
        if (mMaxLinesForHeight > 0) {
            maxLines = mMaxLinesForHeight;
        } else {
            maxLines = getMaxLines() >= 0 ? getMaxLines() : Integer.MAX_VALUE;
        }
        builder.setMaxLines(maxLines);
        mLayoutMaxLines = maxLines;
        if (shouldEllipsize) {
            builder.setEllipsize(effectiveEllipsize)
                    .setEllipsizedWidth(ellipsisWidth);
@@ -98,6 +109,34 @@ public class ImageFloatingTextView extends TextView {
        return builder.build();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        // Lets calculate how many lines the given measurement allows us.
        int availableHeight = height - mPaddingTop - mPaddingBottom;
        int maxLines = availableHeight / getLineHeight();
        if (getMaxLines() > 0) {
            maxLines = Math.min(getMaxLines(), maxLines);
        }
        if (maxLines != mMaxLinesForHeight) {
            mMaxLinesForHeight = maxLines;
            if (getLayout() != null && mMaxLinesForHeight != mLayoutMaxLines) {
                // Invalidate layout.
                mBlockLayouts = true;
                setHint(getHint());
                mBlockLayouts = false;
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public void requestLayout() {
        if (!mBlockLayouts) {
            super.requestLayout();
        }
    }

    @Override
    public void onRtlPropertiesChanged(int layoutDirection) {
        super.onRtlPropertiesChanged(layoutDirection);
+57 −56
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.widget.RemoteViews;
@RemoteViews.RemoteView
public class MessagingLinearLayout extends ViewGroup {

    private static final int NOT_MEASURED_BEFORE = -1;
    /**
     * Spacing to be applied between views.
     */
@@ -52,6 +53,11 @@ public class MessagingLinearLayout extends ViewGroup {
     * Id of the child that's also visible in the contracted layout.
     */
    private int mContractedChildId;
    /**
     * The last measured with in a layout pass if it was measured before or
     * {@link #NOT_MEASURED_BEFORE} if this is the first layout pass.
     */
    private int mLastMeasuredWidth = NOT_MEASURED_BEFORE;

    public MessagingLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
@@ -64,20 +70,12 @@ public class MessagingLinearLayout extends ViewGroup {
        for (int i = 0; i < N; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.MessagingLinearLayout_maxHeight:
                    mMaxHeight = a.getDimensionPixelSize(i, 0);
                    break;
                case R.styleable.MessagingLinearLayout_spacing:
                    mSpacing = a.getDimensionPixelSize(i, 0);
                    break;
            }
        }

        if (mMaxHeight <= 0) {
            throw new IllegalStateException(
                    "MessagingLinearLayout: Must specify positive maxHeight");
        }

        a.recycle();
    }

@@ -86,24 +84,23 @@ public class MessagingLinearLayout extends ViewGroup {
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // This is essentially a bottom-up linear layout that only adds children that fit entirely
        // up to a maximum height.

        int targetHeight = MeasureSpec.getSize(heightMeasureSpec);
        switch (MeasureSpec.getMode(heightMeasureSpec)) {
            case MeasureSpec.AT_MOST:
                heightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        Math.min(mMaxHeight, MeasureSpec.getSize(heightMeasureSpec)),
                        MeasureSpec.AT_MOST);
                break;
            case MeasureSpec.UNSPECIFIED:
                heightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        mMaxHeight,
                        MeasureSpec.AT_MOST);
                break;
            case MeasureSpec.EXACTLY:
                targetHeight = Integer.MAX_VALUE;
                break;
        }
        final int targetHeight = MeasureSpec.getSize(heightMeasureSpec);
        final int count = getChildCount();
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        boolean recalculateVisibility = mLastMeasuredWidth == NOT_MEASURED_BEFORE
                || getMeasuredHeight() != targetHeight
                || mLastMeasuredWidth != widthSize;

        final int count = getChildCount();
        if (recalculateVisibility) {
            // We only need to recalculate the view visibilities if the view wasn't measured already
            // in this pass, otherwise we may drop messages here already since we are measured
            // exactly with what we returned before, which was optimized already with the
            // line-indents.
            for (int i = 0; i < count; ++i) {
                final View child = getChildAt(i);
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
@@ -114,6 +111,7 @@ public class MessagingLinearLayout extends ViewGroup {
            boolean first = true;

            // Starting from the bottom: we measure every view as if it were the only one. If it still

            // fits, we take it, otherwise we stop there.
            for (int i = count - 1; i >= 0 && totalHeight < targetHeight; i--) {
                if (getChildAt(i).getVisibility() == GONE) {
@@ -144,13 +142,14 @@ public class MessagingLinearLayout extends ViewGroup {
                    break;
                }
            }
        }

        // Now that we know which views to take, fix up the indents and see what width we get.
        int measuredWidth = mPaddingLeft + mPaddingRight;
        int imageLines = mIndentLines;
        // Need to redo the height because it may change due to changing indents.
        totalHeight = mPaddingTop + mPaddingBottom;
        first = true;
        int totalHeight = mPaddingTop + mPaddingBottom;
        boolean first = true;
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
@@ -168,7 +167,7 @@ public class MessagingLinearLayout extends ViewGroup {
                    imageLines = 3;
                }
                boolean changed = textChild.setNumIndentLines(Math.max(0, imageLines));
                if (changed) {
                if (changed || !recalculateVisibility) {
                    measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
                }
                imageLines -= textChild.getLineCount();
@@ -188,6 +187,7 @@ public class MessagingLinearLayout extends ViewGroup {
                        widthMeasureSpec),
                resolveSize(Math.max(getSuggestedMinimumHeight(), totalHeight),
                        heightMeasureSpec));
        mLastMeasuredWidth = widthSize;
    }

    @Override
@@ -236,6 +236,7 @@ public class MessagingLinearLayout extends ViewGroup {

            first = false;
        }
        mLastMeasuredWidth = NOT_MEASURED_BEFORE;
    }

    @Override
+1 −2
Original line number Diff line number Diff line
@@ -48,12 +48,11 @@
            <include layout="@layout/notification_template_progress" />
            <com.android.internal.widget.ImageFloatingTextView android:id="@+id/big_text"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/notification_text_margin_top"
                android:paddingBottom="@dimen/notification_content_margin_bottom"
                android:textAppearance="@style/TextAppearance.Material.Notification"
                android:singleLine="false"
                android:layout_weight="1"
                android:gravity="top"
                android:visibility="gone"
                />
+1 −2
Original line number Diff line number Diff line
@@ -50,8 +50,7 @@
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingBottom="@dimen/notification_content_margin_bottom"
                android:spacing="@dimen/notification_messaging_spacing"
                android:maxHeight="165dp">
                android:spacing="@dimen/notification_messaging_spacing" >
                <com.android.internal.widget.ImageFloatingTextView android:id="@+id/inbox_text0"
                    style="@style/Widget.Material.Notification.MessagingText"
                    />
Loading