mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 03:31:45 +08:00
Fix a crash when nesting a ProxyViewContainer in FlexboxLayout.
Conflicts: tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout.ios.ts
This commit is contained in:

committed by
Hristo Deshev

parent
ce72b60763
commit
ac90b9db2b
@ -1911,6 +1911,20 @@ export const testWrap_childMargin_vertical = test(
|
||||
}
|
||||
);
|
||||
|
||||
let activity_flexbox_with_proxy_view_container = () => getViews(
|
||||
`<FlexboxLayout id="flexbox">
|
||||
<ProxyViewContainer></ProxyViewContainer>
|
||||
</FlexboxLayout>`
|
||||
);
|
||||
|
||||
export const testFlexboxLayout_does_not_crash_with_proxy_view_container = test(
|
||||
activity_flexbox_with_proxy_view_container,
|
||||
noop,
|
||||
({root, flexbox}) => {
|
||||
TKUnit.assert(flexbox.id === "flexbox", "FlexboxLayout actually there");
|
||||
}
|
||||
);
|
||||
|
||||
// Omit testEmptyChildren
|
||||
// Omit testDivider_directionRow_verticalBeginning
|
||||
|
||||
|
@ -94,6 +94,28 @@ import makeMeasureSpec = layout.makeMeasureSpec;
|
||||
import getMeasureSpecMode = layout.getMeasureSpecMode;
|
||||
import getMeasureSpecSize = layout.getMeasureSpecSize;
|
||||
|
||||
// `eachLayoutChild` iterates over children, and we need more - indexed access.
|
||||
// This class tries to accomodate that by collecting all children in an
|
||||
// array no more than once per measure.
|
||||
class MeasureContext {
|
||||
private children: View[];
|
||||
|
||||
constructor(private owner: FlexboxLayout) {
|
||||
this.children = [];
|
||||
this.owner.eachLayoutChild((child) => {
|
||||
this.children.push(child);
|
||||
});
|
||||
}
|
||||
|
||||
public get childrenCount(): number {
|
||||
return this.children.length;
|
||||
}
|
||||
|
||||
public childAt(index: number): View {
|
||||
return this.children[index];
|
||||
}
|
||||
}
|
||||
|
||||
class FlexLine {
|
||||
|
||||
_left: number = Number.MAX_VALUE;
|
||||
@ -144,15 +166,17 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
private _orderCache: number[];
|
||||
private _flexLines: FlexLine[] = [];
|
||||
private _childrenFrozen: boolean[];
|
||||
private measureContext: MeasureContext;
|
||||
|
||||
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||
this.measureContext = new MeasureContext(this);
|
||||
// Omit: super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
if (this._isOrderChangedFromLastMeasurement) {
|
||||
this._reorderedIndices = this._createReorderedIndices();
|
||||
}
|
||||
if (!this._childrenFrozen || this._childrenFrozen.length < this.getChildrenCount()) {
|
||||
this._childrenFrozen = new Array(this.getChildrenCount());
|
||||
if (!this._childrenFrozen || this._childrenFrozen.length < this.measureContext.childrenCount) {
|
||||
this._childrenFrozen = new Array(this.measureContext.childrenCount);
|
||||
}
|
||||
|
||||
switch (this.flexDirection) {
|
||||
@ -177,13 +201,13 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
child = null;
|
||||
} else {
|
||||
let reorderedIndex = this._reorderedIndices[index];
|
||||
child = this.getChildAt(reorderedIndex);
|
||||
child = this.measureContext.childAt(reorderedIndex);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
private _createReorderedIndices(): number[] {
|
||||
let childCount = this.getChildrenCount();
|
||||
let childCount = this.measureContext.childrenCount;
|
||||
let orders = this._createOrders(childCount);
|
||||
return this._sortOrdersIntoReorderedIndices(childCount, orders);
|
||||
}
|
||||
@ -206,7 +230,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
private _createOrders(childCount: number): Order[] {
|
||||
let orders: Order[] = [];
|
||||
for (let i = 0; i < childCount; i++) {
|
||||
let child = this.getChildAt(i);
|
||||
let child = this.measureContext.childAt(i);
|
||||
let order = new Order();
|
||||
order.order = FlexboxLayout.getOrder(child);
|
||||
order.index = i;
|
||||
@ -216,7 +240,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
}
|
||||
|
||||
private get _isOrderChangedFromLastMeasurement(): boolean {
|
||||
let childCount = this.getChildrenCount();
|
||||
let childCount = this.measureContext.childrenCount;
|
||||
if (!this._orderCache) {
|
||||
this._orderCache = [];
|
||||
}
|
||||
@ -224,7 +248,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
return true;
|
||||
}
|
||||
for (let i = 0; i < childCount; i++) {
|
||||
let view = this.getChildAt(i);
|
||||
let view = this.measureContext.childAt(i);
|
||||
if (view === null) {
|
||||
continue;
|
||||
}
|
||||
@ -244,7 +268,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
this._flexLines.length = 0;
|
||||
|
||||
(() => {
|
||||
let childCount = this.getChildrenCount();
|
||||
let childCount = this.measureContext.childrenCount;
|
||||
let paddingStart = FlexboxLayout.getPaddingStart(this);
|
||||
let paddingEnd = FlexboxLayout.getPaddingEnd(this);
|
||||
let largestHeightInRow = Number.MIN_VALUE;
|
||||
@ -359,7 +383,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
|
||||
this._flexLines.length = 0;
|
||||
|
||||
let childCount = this.getChildrenCount();
|
||||
let childCount = this.measureContext.childrenCount;
|
||||
let paddingTop = this.effectivePaddingTop;
|
||||
let paddingBottom = this.effectivePaddingBottom;
|
||||
let largestWidthInColumn = Number.MIN_VALUE;
|
||||
|
Reference in New Issue
Block a user