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

Commit 01c0a0ba authored by Jorge Ruesga's avatar Jorge Ruesga Committed by Gerrit Code Review
Browse files

linearlayout: fix measurement of childrens when parent and childrens have exactly the same pixels

When children measure exactly the same width/height than the parent, any child with
width/height == 0 and with weight > 0 must be reset. Otherwise, the view will retains
the same width/height between measurements calls (that is not valid if the view changed
its orientation).

This explain the bug in CYAN-5471 when in hpdi devices the spacer view has the same
width after rotate from landscape to portrait when language is german and date beewteen
September 10-30. Steps to repro in i9100 (hdpi):

1.- Set language to german and date to September, 10.
2.- First run, the expanded bar has the same width that its children (480px the current
screen size), but spacer has 0px (because it isn't being measured by linearlayout).
3.- Rotate to landscape, spacer gains space and all buttons are displayed correctly.
4.- Rotate to portrait, spacer has the same width that in step 3, because it isn't measured
again and delta == 0;

This patch forces this views to be re-measured to 0 to match the current delta (the views doesn't
need to be expanded or shrinked).

JIRA: CYAN-5471
https://jira.cyanogenmod.org/browse/CYAN-5471


Signed-off-by: default avatarJorge Ruesga <jorge@ruesga.com>

Change-Id: Iab60337eca6ded7b2b4d57fdcc95863be461db34
parent 650b579e
Loading
Loading
Loading
Loading
+49 −3
Original line number Diff line number Diff line
@@ -801,9 +801,32 @@ public class LinearLayout extends ViewGroup {
        int heightSizeAndState = resolveSizeAndState(heightSize, heightMeasureSpec, 0);
        heightSize = heightSizeAndState & MEASURED_SIZE_MASK;
        
        int delta = heightSize - mTotalLength;

        // When children measure exactly the same height than the parent, any child with
        // height == 0 and with weight > 0 must be reset. Otherwise, the view will retains
        // the same height between measurements calls (that is not valid if the view changed
        // its orientation)
        if (delta == 0 && totalWeight > 0.0f) {
            for (int i = 0; i < count; ++i) {
                final View child = getVirtualChildAt(i);

                if (child == null || child.getVisibility() == View.GONE) {
                    continue;
                }

                final LinearLayout.LayoutParams lp =
                        (LinearLayout.LayoutParams) child.getLayoutParams();

                if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
                    final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(freeSpec, freeSpec);
                }
            }
        }

        // Either expand children with weight to take up available space or
        // shrink them if they extend beyond our current bounds
        int delta = heightSize - mTotalLength;
        if (delta != 0 && totalWeight > 0.0f) {
            float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;

@@ -1179,9 +1202,32 @@ public class LinearLayout extends ViewGroup {
        int widthSizeAndState = resolveSizeAndState(widthSize, widthMeasureSpec, 0);
        widthSize = widthSizeAndState & MEASURED_SIZE_MASK;

        int delta = widthSize - mTotalLength;

        // When children measure exactly the same width than the parent, any child with
        // width == 0 and with weight > 0 must be reset. Otherwise, the view will retains
        // the same width between measurements calls (that is not valid if the view changed
        // its orientation). If the view is baselineAligned, a precalculation was made previously
        if (!baselineAligned && delta == 0 && totalWeight > 0.0f) {
            for (int i = 0; i < count; ++i) {
                final View child = getVirtualChildAt(i);

                if (child == null || child.getVisibility() == View.GONE) {
                    continue;
                }

                final LinearLayout.LayoutParams lp =
                        (LinearLayout.LayoutParams) child.getLayoutParams();

                if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) {
                    final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(freeSpec, freeSpec);
                }
            }
        }

        // Either expand children with weight to take up available space or
        // shrink them if they extend beyond our current bounds
        int delta = widthSize - mTotalLength;
        if (delta != 0 && totalWeight > 0.0f) {
            float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;