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

Commit dae97c94 authored by Selim Cinek's avatar Selim Cinek
Browse files

Fixed measuring of messages with excess space

Sometimes the layout was measured too big, with additional
white space that wasn't needed because of the way excess
space was handled.

Test: manual write 3 single line messages and 2 two line
Bug: 63708826
Change-Id: I09e728e87e316cb770d5c65bf355a68848e58f0b
parent f7409dbb
Loading
Loading
Loading
Loading
+46 −69
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import com.android.internal.R;
@RemoteViews.RemoteView
public class MessagingLinearLayout extends ViewGroup {

    private static final int NOT_MEASURED_BEFORE = -1;
    /**
     * Spacing to be applied between views.
     */
@@ -44,15 +43,6 @@ public class MessagingLinearLayout extends ViewGroup {

    private int mMaxDisplayedLines = Integer.MAX_VALUE;

    /**
     * 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;
    private MessagingLayout mMessagingLayout;

    public MessagingLinearLayout(Context context, @Nullable AttributeSet attrs) {
@@ -86,19 +76,11 @@ public class MessagingLinearLayout extends ViewGroup {
                break;
        }
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        boolean recalculateVisibility = mLastMeasuredWidth == NOT_MEASURED_BEFORE
                || getMeasuredHeight() != targetHeight
                || mLastMeasuredWidth != widthSize;

        // Now that we know which views to take, fix up the indents and see what width we get.
        int measuredWidth = mPaddingLeft + mPaddingRight;
        final int count = getChildCount();
        int totalHeight = getMeasuredHeight();
        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.
        int totalHeight;
        for (int i = 0; i < count; ++i) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
@@ -110,7 +92,6 @@ public class MessagingLinearLayout extends ViewGroup {
        int linesRemaining = mMaxDisplayedLines;

        // 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) {
@@ -151,14 +132,11 @@ public class MessagingLinearLayout extends ViewGroup {
                break;
            }
        }
        }

        setMeasuredDimension(
                resolveSize(Math.max(getSuggestedMinimumWidth(), measuredWidth),
                        widthMeasureSpec),
                resolveSize(Math.max(getSuggestedMinimumHeight(), totalHeight),
                        heightMeasureSpec));
        mLastMeasuredWidth = widthSize;
                Math.max(getSuggestedMinimumHeight(), totalHeight));
    }

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

            first = false;
        }
        mLastMeasuredWidth = NOT_MEASURED_BEFORE;
    }

    @Override
+68 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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
 */

package com.android.internal.widget;

import android.annotation.Nullable;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RemoteViews;

/**
 * A LinearLayout that sets it's height again after the last measure pass. This is needed for
 * MessagingLayouts where groups need to be able to snap it's height to.
 */
@RemoteViews.RemoteView
public class RemeasuringLinearLayout extends LinearLayout {

    public RemeasuringLinearLayout(Context context) {
        super(context);
    }

    public RemeasuringLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public RemeasuringLinearLayout(Context context, @Nullable AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public RemeasuringLinearLayout(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int count = getChildCount();
        int height = 0;
        for (int i = 0; i < count; ++i) {
            final View child = getChildAt(i);
            if (child == null || child.getVisibility() == View.GONE) {
                continue;
            }

            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            height = Math.max(height, height + child.getMeasuredHeight() + lp.topMargin +
                    lp.bottomMargin);
        }
        setMeasuredDimension(getMeasuredWidth(), height);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@
        android:layout_marginEnd="8dp"
        android:scaleType="centerCrop"
        android:importantForAccessibility="no" />
    <LinearLayout
    <com.android.internal.widget.RemeasuringLinearLayout
        android:id="@+id/message_group_and_sender_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
@@ -46,5 +46,5 @@
            android:paddingEnd="8dp"
            android:paddingTop="2dp"
        />
    </LinearLayout>
    </com.android.internal.widget.RemeasuringLinearLayout>
</com.android.internal.widget.MessagingGroup>