Skip to content

Commit cc18909

Browse files
authored
fix(core): FlexboxLayout nested views alignment corrections (#10766)
1 parent f820dc1 commit cc18909

File tree

4 files changed

+89
-33
lines changed

4 files changed

+89
-33
lines changed
233 Bytes
Binary file not shown.

packages/core/ui/layouts/flexbox-layout/index.ios.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class FlexLine {
6767
_dividerLengthInMainSize = 0;
6868
_crossSize = 0;
6969
_itemCount = 0;
70+
_goneItemCount = 0;
7071
_totalFlexGrow = 0;
7172
_totalFlexShrink = 0;
7273
_maxBaseline = 0;
@@ -95,6 +96,9 @@ class FlexLine {
9596
get itemCount(): number {
9697
return this._itemCount;
9798
}
99+
get layoutVisibleItemCount(): number {
100+
return this._itemCount - this._goneItemCount;
101+
}
98102
get totalFlexGrow(): number {
99103
return this._totalFlexGrow;
100104
}
@@ -249,6 +253,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
249253
continue;
250254
} else if (child.isCollapsed) {
251255
flexLine._itemCount++;
256+
flexLine._goneItemCount++;
252257
this._addFlexLineIfLastFlexItem(i, childCount, flexLine);
253258
continue;
254259
}
@@ -276,7 +281,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
276281
largestHeightInRow = Math.max(largestHeightInRow, child.getMeasuredHeight() + lp.effectiveMarginTop + lp.effectiveMarginBottom);
277282

278283
if (this._isWrapRequired(child, widthMode, widthSize, flexLine._mainSize, child.getMeasuredWidth() + lp.effectiveMarginLeft + lp.effectiveMarginRight, i, indexInFlexLine)) {
279-
if (flexLine.itemCount > 0) {
284+
if (flexLine.layoutVisibleItemCount > 0) {
280285
this._addFlexLine(flexLine);
281286
}
282287

@@ -318,11 +323,11 @@ export class FlexboxLayout extends FlexboxLayoutBase {
318323
if (this.flexWrap !== FlexWrap.WRAP_REVERSE) {
319324
let marginTop = flexLine._maxBaseline - FlexboxLayout.getBaseline(child);
320325
marginTop = Math.max(marginTop, lp.effectiveMarginTop);
321-
largestHeightInLine = Math.max(largestHeightInLine, child.getActualSize().height + marginTop + lp.effectiveMarginBottom);
326+
largestHeightInLine = Math.max(largestHeightInLine, child.getMeasuredHeight() + marginTop + lp.effectiveMarginBottom);
322327
} else {
323328
let marginBottom = flexLine._maxBaseline - child.getMeasuredHeight() + FlexboxLayout.getBaseline(child);
324329
marginBottom = Math.max(marginBottom, lp.effectiveMarginBottom);
325-
largestHeightInLine = Math.max(largestHeightInLine, child.getActualSize().height + lp.effectiveMarginTop + marginBottom);
330+
largestHeightInLine = Math.max(largestHeightInLine, child.getMeasuredHeight() + lp.effectiveMarginTop + marginBottom);
326331
}
327332
}
328333
flexLine._crossSize = largestHeightInLine;
@@ -359,6 +364,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
359364
continue;
360365
} else if (child.isCollapsed) {
361366
flexLine._itemCount++;
367+
flexLine._goneItemCount++;
362368
this._addFlexLineIfLastFlexItem(i, childCount, flexLine);
363369
continue;
364370
}
@@ -385,7 +391,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
385391
largestWidthInColumn = Math.max(largestWidthInColumn, child.getMeasuredWidth() + lp.effectiveMarginLeft + lp.effectiveMarginRight);
386392

387393
if (this._isWrapRequired(child, heightMode, heightSize, flexLine.mainSize, child.getMeasuredHeight() + lp.effectiveMarginTop + lp.effectiveMarginBottom, i, indexInFlexLine)) {
388-
if (flexLine._itemCount > 0) {
394+
if (flexLine.layoutVisibleItemCount > 0) {
389395
this._addFlexLine(flexLine);
390396
}
391397

@@ -447,7 +453,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
447453
}
448454

449455
private _addFlexLineIfLastFlexItem(childIndex: number, childCount: number, flexLine: FlexLine) {
450-
if (childIndex === childCount - 1 && flexLine.itemCount !== 0) {
456+
if (childIndex === childCount - 1 && flexLine.layoutVisibleItemCount !== 0) {
451457
this._addFlexLine(flexLine);
452458
}
453459
}
@@ -1012,16 +1018,20 @@ export class FlexboxLayout extends FlexboxLayoutBase {
10121018
childLeft = paddingLeft + (width - insets.left - insets.right - flexLine._mainSize) / 2.0;
10131019
childRight = width - paddingRight - (width - insets.left - insets.right - flexLine._mainSize) / 2.0;
10141020
break;
1015-
case JustifyContent.SPACE_AROUND:
1016-
if (flexLine._itemCount !== 0) {
1017-
spaceBetweenItem = (width - insets.left - insets.right - flexLine.mainSize) / flexLine._itemCount;
1021+
case JustifyContent.SPACE_AROUND: {
1022+
const visibleCount = flexLine.layoutVisibleItemCount;
1023+
if (visibleCount !== 0) {
1024+
spaceBetweenItem = (width - insets.left - insets.right - flexLine.mainSize) / visibleCount;
10181025
}
10191026
childLeft = paddingLeft + spaceBetweenItem / 2.0;
10201027
childRight = width - paddingRight - spaceBetweenItem / 2.0;
10211028
break;
1029+
}
10221030
case JustifyContent.SPACE_BETWEEN: {
1031+
const visibleCount = flexLine.layoutVisibleItemCount;
1032+
const denominator = visibleCount !== 1 ? visibleCount - 1 : 1.0;
1033+
10231034
childLeft = paddingLeft;
1024-
const denominator = flexLine.itemCount !== 1 ? flexLine.itemCount - 1 : 1.0;
10251035
spaceBetweenItem = (width - insets.left - insets.right - flexLine.mainSize) / denominator;
10261036
childRight = width - paddingRight;
10271037
break;
@@ -1156,16 +1166,20 @@ export class FlexboxLayout extends FlexboxLayoutBase {
11561166
childTop = paddingTop + (height - insets.top - insets.bottom - flexLine._mainSize) / 2.0;
11571167
childBottom = height - paddingBottom - (height - insets.top - insets.bottom - flexLine._mainSize) / 2.0;
11581168
break;
1159-
case JustifyContent.SPACE_AROUND:
1160-
if (flexLine._itemCount !== 0) {
1161-
spaceBetweenItem = (height - insets.top - insets.bottom - flexLine._mainSize) / flexLine.itemCount;
1169+
case JustifyContent.SPACE_AROUND: {
1170+
const visibleCount = flexLine.layoutVisibleItemCount;
1171+
if (visibleCount !== 0) {
1172+
spaceBetweenItem = (height - insets.top - insets.bottom - flexLine._mainSize) / visibleCount;
11621173
}
11631174
childTop = paddingTop + spaceBetweenItem / 2.0;
11641175
childBottom = height - paddingBottom - spaceBetweenItem / 2.0;
11651176
break;
1177+
}
11661178
case JustifyContent.SPACE_BETWEEN: {
1179+
const visibleCount = flexLine.layoutVisibleItemCount;
1180+
const denominator = visibleCount !== 1 ? visibleCount - 1 : 1.0;
1181+
11671182
childTop = paddingTop;
1168-
const denominator = flexLine.itemCount !== 1 ? flexLine.itemCount - 1 : 1.0;
11691183
spaceBetweenItem = (height - insets.top - insets.bottom - flexLine.mainSize) / denominator;
11701184
childBottom = height - paddingBottom;
11711185
break;

packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/FlexLine.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ public class FlexLine {
7070
*/
7171
int mItemCount;
7272

73+
/** Holds the count of the views whose visibilities are gone */
74+
int mGoneItemCount;
75+
7376
/**
7477
* @see {@link #getTotalFlexGrow()}
7578
*/
@@ -151,6 +154,13 @@ public int getItemCount() {
151154
return mItemCount;
152155
}
153156

157+
/**
158+
* @return the count of the views whose visibilities are not gone in this flex line.
159+
*/
160+
public int getLayoutVisibleItemCount() {
161+
return mItemCount - mGoneItemCount;
162+
}
163+
154164
/**
155165
* @return the sum of the flexGrow properties of the children included in this flex line
156166
*/

packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ private void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
583583
continue;
584584
} else if (child.getVisibility() == View.GONE) {
585585
flexLine.mItemCount++;
586+
flexLine.mGoneItemCount++;
586587
addFlexLineIfLastFlexItem(i, childCount, flexLine);
587588
continue;
588589
}
@@ -627,7 +628,7 @@ private void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
627628
if (isWrapRequired(widthMode, widthSize, flexLine.mMainSize,
628629
child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin, lp,
629630
i, indexInFlexLine)) {
630-
if (flexLine.mItemCount > 0) {
631+
if (flexLine.getLayoutVisibleItemCount() > 0) {
631632
addFlexLine(flexLine);
632633
}
633634

@@ -681,17 +682,18 @@ private void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
681682
for (int i = viewIndex; i < viewIndex + flexLine.mItemCount; i++) {
682683
View child = getReorderedChildAt(i);
683684
LayoutParams lp = (LayoutParams) child.getLayoutParams();
685+
684686
if (mFlexWrap != FLEX_WRAP_WRAP_REVERSE) {
685687
int marginTop = flexLine.mMaxBaseline - child.getBaseline();
686688
marginTop = Math.max(marginTop, lp.topMargin);
687689
largestHeightInLine = Math.max(largestHeightInLine,
688-
child.getHeight() + marginTop + lp.bottomMargin);
690+
child.getMeasuredHeight() + marginTop + lp.bottomMargin);
689691
} else {
690692
int marginBottom = flexLine.mMaxBaseline - child.getMeasuredHeight() +
691693
child.getBaseline();
692694
marginBottom = Math.max(marginBottom, lp.bottomMargin);
693695
largestHeightInLine = Math.max(largestHeightInLine,
694-
child.getHeight() + lp.topMargin + marginBottom);
696+
child.getMeasuredHeight() + lp.topMargin + marginBottom);
695697
}
696698
}
697699
flexLine.mCrossSize = largestHeightInLine;
@@ -745,6 +747,7 @@ private void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
745747
continue;
746748
} else if (child.getVisibility() == View.GONE) {
747749
flexLine.mItemCount++;
750+
flexLine.mGoneItemCount++;
748751
addFlexLineIfLastFlexItem(i, childCount, flexLine);
749752
continue;
750753
}
@@ -790,7 +793,7 @@ private void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
790793
if (isWrapRequired(heightMode, heightSize, flexLine.mMainSize,
791794
child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin, lp,
792795
i, indexInFlexLine)) {
793-
if (flexLine.mItemCount > 0) {
796+
if (flexLine.getLayoutVisibleItemCount() > 0) {
794797
addFlexLine(flexLine);
795798
}
796799

@@ -862,7 +865,7 @@ private void checkSizeConstraints(View view) {
862865
}
863866

864867
private void addFlexLineIfLastFlexItem(int childIndex, int childCount, FlexLine flexLine) {
865-
if (childIndex == childCount - 1 && flexLine.mItemCount != 0) {
868+
if (childIndex == childCount - 1 && flexLine.getLayoutVisibleItemCount() != 0) {
866869
// Add the flex line if this item is the last item
867870
addFlexLine(flexLine);
868871
}
@@ -1661,20 +1664,25 @@ private void layoutHorizontal(boolean isRtl, int left, int top, int right, int b
16611664
childLeft = paddingLeft + (width - flexLine.mMainSize) / 2f;
16621665
childRight = width - paddingRight - (width - flexLine.mMainSize) / 2f;
16631666
break;
1664-
case JUSTIFY_CONTENT_SPACE_AROUND:
1665-
if (flexLine.mItemCount != 0) {
1667+
case JUSTIFY_CONTENT_SPACE_AROUND: {
1668+
int visibleCount = flexLine.getLayoutVisibleItemCount();
1669+
if (visibleCount != 0) {
16661670
spaceBetweenItem = (width - flexLine.mMainSize)
1667-
/ (float) flexLine.mItemCount;
1671+
/ (float) visibleCount;
16681672
}
16691673
childLeft = paddingLeft + spaceBetweenItem / 2f;
16701674
childRight = width - paddingRight - spaceBetweenItem / 2f;
16711675
break;
1672-
case JUSTIFY_CONTENT_SPACE_BETWEEN:
1676+
}
1677+
case JUSTIFY_CONTENT_SPACE_BETWEEN: {
1678+
int visibleCount = flexLine.getLayoutVisibleItemCount();
1679+
float denominator = visibleCount != 1 ? visibleCount - 1 : 1f;
1680+
16731681
childLeft = paddingLeft;
1674-
float denominator = flexLine.mItemCount != 1 ? flexLine.mItemCount - 1 : 1f;
16751682
spaceBetweenItem = (width - flexLine.mMainSize) / denominator;
16761683
childRight = width - paddingRight;
16771684
break;
1685+
}
16781686
default:
16791687
throw new IllegalStateException(
16801688
"Invalid justifyContent is set: " + mJustifyContent);
@@ -1878,20 +1886,25 @@ private void layoutVertical(boolean isRtl, boolean fromBottomToTop, int left, in
18781886
childTop = paddingTop + (height - flexLine.mMainSize) / 2f;
18791887
childBottom = height - paddingBottom - (height - flexLine.mMainSize) / 2f;
18801888
break;
1881-
case JUSTIFY_CONTENT_SPACE_AROUND:
1882-
if (flexLine.mItemCount != 0) {
1889+
case JUSTIFY_CONTENT_SPACE_AROUND: {
1890+
int visibleCount = flexLine.getLayoutVisibleItemCount();
1891+
if (visibleCount != 0) {
18831892
spaceBetweenItem = (height - flexLine.mMainSize)
1884-
/ (float) flexLine.mItemCount;
1893+
/ (float) visibleCount;
18851894
}
18861895
childTop = paddingTop + spaceBetweenItem / 2f;
18871896
childBottom = height - paddingBottom - spaceBetweenItem / 2f;
18881897
break;
1889-
case JUSTIFY_CONTENT_SPACE_BETWEEN:
1898+
}
1899+
case JUSTIFY_CONTENT_SPACE_BETWEEN: {
1900+
int visibleCount = flexLine.getLayoutVisibleItemCount();
1901+
float denominator = visibleCount != 1 ? visibleCount - 1 : 1f;
1902+
18901903
childTop = paddingTop;
1891-
float denominator = flexLine.mItemCount != 1 ? flexLine.mItemCount - 1 : 1f;
18921904
spaceBetweenItem = (height - flexLine.mMainSize) / denominator;
18931905
childBottom = height - paddingBottom;
18941906
break;
1907+
}
18951908
default:
18961909
throw new IllegalStateException(
18971910
"Invalid justifyContent is set: " + mJustifyContent);
@@ -2085,6 +2098,11 @@ private void drawDividersHorizontal(Canvas canvas, boolean isRtl, boolean fromBo
20852098
FlexLine flexLine = mFlexLines.get(i);
20862099
for (int j = 0; j < flexLine.mItemCount; j++) {
20872100
View view = getReorderedChildAt(currentViewIndex);
2101+
2102+
if (view == null || view.getVisibility() == View.GONE) {
2103+
continue;
2104+
}
2105+
20882106
LayoutParams lp = (LayoutParams) view.getLayoutParams();
20892107

20902108
// Judge if the beginning or middle divider is needed
@@ -2165,6 +2183,11 @@ private void drawDividersVertical(Canvas canvas, boolean isRtl, boolean fromBott
21652183
// Draw horizontal dividers if needed
21662184
for (int j = 0; j < flexLine.mItemCount; j++) {
21672185
View view = getReorderedChildAt(currentViewIndex);
2186+
2187+
if (view == null || view.getVisibility() == View.GONE) {
2188+
continue;
2189+
}
2190+
21682191
LayoutParams lp = (LayoutParams) view.getLayoutParams();
21692192

21702193
// Judge if the beginning or middle divider is needed
@@ -2332,11 +2355,20 @@ public void setAlignContent(@AlignContent int alignContent) {
23322355
}
23332356

23342357
/**
2335-
* @return the flex lines composing this flex container. This method returns an unmodifiable
2336-
* list. Thus any changes of the returned list are not supported.
2358+
* @return the flex lines composing this flex container. This method returns a copy of the
2359+
* original list excluding a dummy flex line (flex line that doesn't have any flex items in it
2360+
* but used for the alignment along the cross axis).
2361+
* Thus any changes of the returned list are not reflected to the original list.
23372362
*/
23382363
public List<FlexLine> getFlexLines() {
2339-
return Collections.unmodifiableList(mFlexLines);
2364+
List<FlexLine> result = new ArrayList<>(mFlexLines.size());
2365+
for (FlexLine flexLine : mFlexLines) {
2366+
if (flexLine.getLayoutVisibleItemCount() == 0) {
2367+
continue;
2368+
}
2369+
result.add(flexLine);
2370+
}
2371+
return result;
23402372
}
23412373

23422374
/**
@@ -2535,7 +2567,7 @@ private boolean hasDividerBeforeFlexLine(int flexLineIndex) {
25352567

25362568
private boolean allFlexLinesAreDummyBefore(int flexLineIndex) {
25372569
for (int i = 0; i < flexLineIndex; i++) {
2538-
if (mFlexLines.get(i).mItemCount > 0) {
2570+
if (mFlexLines.get(i).getLayoutVisibleItemCount() > 0) {
25392571
return false;
25402572
}
25412573
}
@@ -2554,7 +2586,7 @@ private boolean hasEndDividerAfterFlexLine(int flexLineIndex) {
25542586
}
25552587

25562588
for (int i = flexLineIndex + 1; i < mFlexLines.size(); i++) {
2557-
if (mFlexLines.get(i).mItemCount > 0) {
2589+
if (mFlexLines.get(i).getLayoutVisibleItemCount() > 0) {
25582590
return false;
25592591
}
25602592
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy