mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Fix a crash when nesting a ProxyViewContainer in FlexboxLayout.
This commit is contained in:
committed by
Hristo Deshev
parent
e0b0e46f70
commit
18739f8cd1
@@ -1975,6 +1975,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 testEmptyChildren
|
||||||
// Omit testDivider_directionRow_verticalBeginning
|
// Omit testDivider_directionRow_verticalBeginning
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,28 @@ import makeMeasureSpec = utils.layout.makeMeasureSpec;
|
|||||||
import getMeasureSpecMode = utils.layout.getMeasureSpecMode;
|
import getMeasureSpecMode = utils.layout.getMeasureSpecMode;
|
||||||
import getMeasureSpecSize = utils.layout.getMeasureSpecSize;
|
import getMeasureSpecSize = utils.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 {
|
class FlexLine {
|
||||||
|
|
||||||
_left: number = Number.MAX_VALUE;
|
_left: number = Number.MAX_VALUE;
|
||||||
@@ -117,6 +139,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
private _orderCache: number[];
|
private _orderCache: number[];
|
||||||
private _flexLines: FlexLine[] = [];
|
private _flexLines: FlexLine[] = [];
|
||||||
private _childrenFrozen: boolean[];
|
private _childrenFrozen: boolean[];
|
||||||
|
private measureContext: MeasureContext;
|
||||||
|
|
||||||
_setNativeFlexDirection(flexDirection: FlexDirection) {
|
_setNativeFlexDirection(flexDirection: FlexDirection) {
|
||||||
// lint happy no-op
|
// lint happy no-op
|
||||||
@@ -141,6 +164,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||||
|
this.measureContext = new MeasureContext(this);
|
||||||
LayoutBase.adjustChildrenLayoutParams(this, widthMeasureSpec, heightMeasureSpec);
|
LayoutBase.adjustChildrenLayoutParams(this, widthMeasureSpec, heightMeasureSpec);
|
||||||
|
|
||||||
// Omit: super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
// Omit: super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
@@ -148,8 +172,8 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
if (this._isOrderChangedFromLastMeasurement) {
|
if (this._isOrderChangedFromLastMeasurement) {
|
||||||
this._reorderedIndices = this._createReorderedIndices();
|
this._reorderedIndices = this._createReorderedIndices();
|
||||||
}
|
}
|
||||||
if (!this._childrenFrozen || this._childrenFrozen.length < this.getChildrenCount()) {
|
if (!this._childrenFrozen || this._childrenFrozen.length < this.measureContext.childrenCount) {
|
||||||
this._childrenFrozen = new Array(this.getChildrenCount());
|
this._childrenFrozen = new Array(this.measureContext.childrenCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (this.flexDirection) {
|
switch (this.flexDirection) {
|
||||||
@@ -174,13 +198,13 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
child = null;
|
child = null;
|
||||||
} else {
|
} else {
|
||||||
let reorderedIndex = this._reorderedIndices[index];
|
let reorderedIndex = this._reorderedIndices[index];
|
||||||
child = this.getChildAt(reorderedIndex);
|
child = this.measureContext.childAt(reorderedIndex);
|
||||||
}
|
}
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createReorderedIndices(): number[] {
|
private _createReorderedIndices(): number[] {
|
||||||
let childCount = this.getChildrenCount();
|
let childCount = this.measureContext.childrenCount;
|
||||||
let orders = this._createOrders(childCount);
|
let orders = this._createOrders(childCount);
|
||||||
return this._sortOrdersIntoReorderedIndices(childCount, orders);
|
return this._sortOrdersIntoReorderedIndices(childCount, orders);
|
||||||
}
|
}
|
||||||
@@ -203,7 +227,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
private _createOrders(childCount: number): Order[] {
|
private _createOrders(childCount: number): Order[] {
|
||||||
let orders: Order[] = [];
|
let orders: Order[] = [];
|
||||||
for (let i = 0; i < childCount; i++) {
|
for (let i = 0; i < childCount; i++) {
|
||||||
let child = this.getChildAt(i);
|
let child = this.measureContext.childAt(i);
|
||||||
let order = new Order();
|
let order = new Order();
|
||||||
order.order = FlexboxLayout.getOrder(child);
|
order.order = FlexboxLayout.getOrder(child);
|
||||||
order.index = i;
|
order.index = i;
|
||||||
@@ -213,7 +237,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _isOrderChangedFromLastMeasurement(): boolean {
|
private get _isOrderChangedFromLastMeasurement(): boolean {
|
||||||
let childCount = this.getChildrenCount();
|
let childCount = this.measureContext.childrenCount;
|
||||||
if (!this._orderCache) {
|
if (!this._orderCache) {
|
||||||
this._orderCache = [];
|
this._orderCache = [];
|
||||||
}
|
}
|
||||||
@@ -221,7 +245,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < childCount; i++) {
|
for (let i = 0; i < childCount; i++) {
|
||||||
let view = this.getChildAt(i);
|
let view = this.measureContext.childAt(i);
|
||||||
if (view === null) {
|
if (view === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -241,7 +265,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
this._flexLines.length = 0;
|
this._flexLines.length = 0;
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
let childCount = this.getChildrenCount();
|
let childCount = this.measureContext.childrenCount;
|
||||||
let paddingStart = FlexboxLayout.getPaddingStart(this);
|
let paddingStart = FlexboxLayout.getPaddingStart(this);
|
||||||
let paddingEnd = FlexboxLayout.getPaddingEnd(this);
|
let paddingEnd = FlexboxLayout.getPaddingEnd(this);
|
||||||
let largestHeightInRow = Number.MIN_VALUE;
|
let largestHeightInRow = Number.MIN_VALUE;
|
||||||
@@ -355,7 +379,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
|||||||
|
|
||||||
this._flexLines.length = 0;
|
this._flexLines.length = 0;
|
||||||
|
|
||||||
let childCount = this.getChildrenCount();
|
let childCount = this.measureContext.childrenCount;
|
||||||
let paddingTop = this.paddingTop;
|
let paddingTop = this.paddingTop;
|
||||||
let paddingBottom = this.paddingBottom;
|
let paddingBottom = this.paddingBottom;
|
||||||
let largestWidthInColumn = Number.MIN_VALUE;
|
let largestWidthInColumn = Number.MIN_VALUE;
|
||||||
|
|||||||
Reference in New Issue
Block a user