Skip to content

Commit 55fc0e4

Browse files
authored
Merge branch 'master' into mdonev/child-fragment-manager-fix
2 parents dbce285 + 436a318 commit 55fc0e4

8 files changed

Lines changed: 50 additions & 37 deletions

File tree

tests/app/ui/layouts/layout-tests-helper.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ export function closeEnough(a: number, b: number, message?: string) {
3333
message ? TKUnit.assertTrue(Math.abs(a - b) <= EPS, message) : TKUnit.assertTrue(Math.abs(a - b) <= EPS);
3434
}
3535

36+
export function lessOrCloseEnough(a: number, b: number, message?: string) {
37+
const less = a < b;
38+
const close = Math.abs(a - b) <= EPS;
39+
message ? TKUnit.assertTrue(less || close, message) : TKUnit.assertTrue(less || close);
40+
}
41+
3642
export function notEqual<T>(a: T, b: T, message?: string) {
3743
message ? TKUnit.assertNotEqual(a, b, message) : TKUnit.assertNotEqual(a, b);
3844
}

tests/app/ui/layouts/safe-area-tests.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,15 @@
1-
import { Page } from "tns-core-modules/ui/page";
2-
import { GridLayout, ItemSpec } from "tns-core-modules/ui/layouts/grid-layout";
3-
import { Button } from "tns-core-modules/ui/button";
1+
import { GridLayout } from "tns-core-modules/ui/layouts/grid-layout";
42
import * as TKUnit from "../../TKUnit";
53
import * as view from "tns-core-modules/ui/core/view";
6-
import { unsetValue } from "tns-core-modules/ui/core/view";
7-
import * as builder from "tns-core-modules/ui/builder";
84
import * as testModule from "../../ui-test";
9-
import * as layoutHelper from "./layout-helper";
105
import * as platform from "tns-core-modules/platform";
116
import { ios as iosUtils } from "tns-core-modules/utils/utils";
12-
import * as commonTests from "./common-layout-tests";
137
import * as helper from "../helper";
148
import { parse } from "tns-core-modules/ui/builder";
159
import {
1610
dipToDp, left, top, right, bottom, height, width,
17-
paddingLeft, paddingTop, paddingRight, paddingBottom,
18-
equal, closeEnough, notEqual, check,
19-
heightEqual, widthEqual,
11+
equal, closeEnough, lessOrCloseEnough, check,
2012
isLeftAlignedWith, isRightAlignedWith, isTopAlignedWith, isBottomAlignedWith,
21-
isLeftOf, isRightOf, isBelow, isAbove,
2213
isLeftWith, isAboveWith, isRightWith, isBelowWith
2314
} from "./layout-tests-helper";
2415

@@ -960,12 +951,12 @@ export class SafeAreaTests extends testModule.UITest<any> {
960951
isAboveWith(cells[2][2], grid, insets.bottom);
961952

962953
closeEnough(height(cells[0][1]), height(cells[1][1]), `cell height should be equal - cell01<${height(cells[0][1])}> - cell11<${height(cells[1][1])}>`);
963-
equal(height(cells[1][1]), height(cells[2][1]), `cell height should be equal - cell11<${height(cells[1][1])}> - cell21<${height(cells[2][1])}>`);
954+
closeEnough(height(cells[1][1]), height(cells[2][1]), `cell height should be equal - cell11<${height(cells[1][1])}> - cell21<${height(cells[2][1])}>`);
964955
const sumOfLabelHeightAndInsets = insets.top + height(cells[0][1]) + height(cells[1][1]) + height(cells[2][1]) + insets.bottom;
965956
closeEnough(height(grid), sumOfLabelHeightAndInsets, `grid height<${height(grid)}> sum of labels height and insets<${sumOfLabelHeightAndInsets}>`);
966957

967-
equal(width(cells[1][0]), width(cells[1][1]), `cell width should be equal - cell10<${width(cells[1][0])}> - cell11<${width(cells[1][1])}>`);
968-
equal(width(cells[1][1]), width(cells[1][2]), `cell width should be equal - cell11<${width(cells[1][1])}> - cell12<${width(cells[1][2])}>`);
958+
closeEnough(width(cells[1][0]), width(cells[1][1]), `cell width should be equal - cell10<${width(cells[1][0])}> - cell11<${width(cells[1][1])}>`);
959+
closeEnough(width(cells[1][1]), width(cells[1][2]), `cell width should be equal - cell11<${width(cells[1][1])}> - cell12<${width(cells[1][2])}>`);
969960
const sumOfLabelWidthsAndInsets = insets.left + width(cells[1][0]) + width(cells[1][1]) + width(cells[1][2]) + insets.right;
970961
equal(width(grid), sumOfLabelWidthsAndInsets, `grid width<${width(grid)}> sum of nested grids width and insets<${sumOfLabelWidthsAndInsets}>`);
971962
},
@@ -1021,7 +1012,7 @@ export class SafeAreaTests extends testModule.UITest<any> {
10211012
isBottomAlignedWith(grid, cells[2][2]);
10221013

10231014
check(height(cells[0][1]) >= height(cells[1][1]), `cell01 height<${height(cells[0][1])}> not greater or equal cell11 height<${height(cells[1][1])}>`);
1024-
check(height(cells[1][1]) <= height(cells[2][1]), `cell11 height<${height(cells[1][1])}> not less or equal cell21 height<${height(cells[2][1])}>`);
1015+
lessOrCloseEnough(height(cells[1][1]), height(cells[2][1]), `cell11 height<${height(cells[1][1])}> not less or equal cell21 height<${height(cells[2][1])}>`);
10251016
const sumOfNestedGridHeights = height(cells[0][1]) + height(cells[1][1]) + height(cells[2][1]);
10261017
equal(height(grid), sumOfNestedGridHeights, `grid height<${height(grid)}> sum of nested grids height <${sumOfNestedGridHeights}>`);
10271018

tests/app/ui/list-view/list-view-safe-area-tests.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { ViewModel } from "./list-view-view-model";
99
import { UITest } from "../../ui-test";
1010
import {
1111
dipToDp, left, top, right, bottom, height, width,
12-
equal, check,
12+
equal, check, lessOrCloseEnough,
1313
isLeftAlignedWith, isRightAlignedWith, isTopAlignedWith
1414
} from "../layouts/layout-tests-helper";
1515

@@ -183,7 +183,7 @@ export class ListViewSafeAreaTest extends UITest<ListView> {
183183
isRightAlignedWith(root, cells[2][2]);
184184

185185
check(height(cells[0][1]) >= height(cells[1][1]), `cell01 height<${height(cells[0][1])}> not greater or equal cell11 height<${height(cells[1][1])}>`);
186-
check(height(cells[1][1]) <= height(cells[2][1]), `cell11 height<${height(cells[1][1])}> not less or equal cell21 height<${height(cells[2][1])}>`);
186+
lessOrCloseEnough(height(cells[1][1]), height(cells[2][1]), `cell11 height<${height(cells[1][1])}> not less or equal cell21 height<${height(cells[2][1])}>`);
187187
const sumOfNestedListViewHeights = height(cells[0][1]) + height(cells[1][1]) + height(cells[2][1]);
188188
equal(height(root), sumOfNestedListViewHeights, `grid height<${height(root)}> sum of nested list views height <${sumOfNestedListViewHeights}>`);
189189

tests/app/ui/scroll-view/scroll-view-safe-area-tests.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as helper from "../helper";
1010
import { parse } from "tns-core-modules/ui/builder";
1111
import {
1212
dipToDp, left, top, right, bottom, height, width,
13-
equal, check,
13+
equal, check, lessOrCloseEnough,
1414
isLeftAlignedWith, isRightAlignedWith, isTopAlignedWith, isBottomAlignedWith,
1515
isLeftWith, isRightWith, isBelowWith
1616
} from "../layouts/layout-tests-helper";
@@ -426,7 +426,7 @@ class ScrollLayoutSafeAreaTest extends UITest<ScrollView> {
426426
isBottomAlignedWith(grid, cells[2][2]);
427427

428428
check(height(cells[0][1]) >= height(cells[1][1]), `cell01 height<${height(cells[0][1])}> not greater or equal cell11 height<${height(cells[1][1])}>`);
429-
check(height(cells[1][1]) <= height(cells[2][1]), `cell11 height<${height(cells[1][1])}> not less or equal cell21 height<${height(cells[2][1])}>`);
429+
lessOrCloseEnough(height(cells[1][1]), height(cells[2][1]), `cell11 height<${height(cells[1][1])}> not less or equal cell21 height<${height(cells[2][1])}>`);
430430
const sumOfNestedScrollViewHeights = height(cells[0][1]) + height(cells[1][1]) + height(cells[2][1]);
431431
equal(height(grid), sumOfNestedScrollViewHeights, `grid height<${height(grid)}> sum of nested scroll views height <${sumOfNestedScrollViewHeights}>`);
432432

tns-core-modules/ui/frame/fragment.transitions.android.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -721,15 +721,6 @@ function toShortString(nativeTransition: android.transition.Transition): string
721721
return `${nativeTransition.getClass().getSimpleName()}@${nativeTransition.hashCode().toString(16)}`;
722722
}
723723

724-
function createDummyZeroDurationAnimation(): android.view.animation.Animation {
725-
// NOTE: returning the dummy AlphaAnimation directly does not work for some reason;
726-
// animationEnd is fired first, then some animationStart (but for a different animation?)
727-
const animationSet = new android.view.animation.AnimationSet(false);
728-
animationSet.addAnimation(new android.view.animation.AlphaAnimation(1, 1));
729-
730-
return animationSet;
731-
}
732-
733724
function printTransitions(entry: ExpandedEntry) {
734725
if (entry && traceEnabled()) {
735726
let result = `${entry.fragmentTag} Transitions:`;
@@ -756,6 +747,14 @@ function printTransitions(entry: ExpandedEntry) {
756747

757748
class NoTransition extends Transition {
758749
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
759-
return createDummyZeroDurationAnimation();
750+
const animation = new android.view.animation.AlphaAnimation(1, 1);
751+
// NOTE: this should not be necessary when we revert to Animators API
752+
// HACK: Android view animation with zero duration seems to be buggy and raises animation listener events in illogical (wrong?) order:
753+
// "enter" start -> "enter" end -> "exit" start -> "exit" end;
754+
// we would expect events to overlap "exit" start -> "enter" start -> "exit" end -> "enter" end, or at least
755+
// "exit" start / end to be raised before "enter" start / end
756+
animation.setDuration(1);
757+
758+
return animation;
760759
}
761760
}

tns-core-modules/ui/frame/frame.android.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,17 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
775775
if (traceEnabled()) {
776776
traceWrite(`${fragment}.onDestroyView()`, traceCategories.NativeLifecycle);
777777
}
778+
779+
// fixes 'java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first'.
780+
// on app resume in nested frame scenarios with support library version greater than 26.0.0
781+
const view = fragment.getView();
782+
if (view != null) {
783+
const viewParent = view.getParent();
784+
if (viewParent instanceof android.view.ViewGroup) {
785+
viewParent.removeView(view);
786+
}
787+
}
788+
778789
superFunc.call(fragment);
779790
}
780791

tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout.ios.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,8 +1003,8 @@ export class FlexboxLayout extends FlexboxLayoutBase {
10031003
childRight = width - paddingRight;
10041004
break;
10051005
case JustifyContent.FLEX_END:
1006-
childLeft = width - flexLine._mainSize - paddingRight;
1007-
childRight = flexLine._mainSize + paddingLeft;
1006+
childLeft = width - flexLine._mainSize + paddingRight;
1007+
childRight = flexLine._mainSize - paddingLeft;
10081008
break;
10091009
case JustifyContent.CENTER:
10101010
childLeft = paddingLeft + (width - insets.left - insets.right - flexLine._mainSize) / 2.0;
@@ -1164,8 +1164,8 @@ export class FlexboxLayout extends FlexboxLayoutBase {
11641164
childBottom = height - paddingBottom;
11651165
break;
11661166
case JustifyContent.FLEX_END:
1167-
childTop = height - flexLine._mainSize - paddingBottom;
1168-
childBottom = flexLine._mainSize + paddingTop;
1167+
childTop = height - flexLine._mainSize + paddingBottom;
1168+
childBottom = flexLine._mainSize - paddingTop;
11691169
break;
11701170
case JustifyContent.CENTER:
11711171
childTop = paddingTop + (height - insets.top - insets.bottom - flexLine._mainSize) / 2.0;

tns-core-modules/ui/repeater/repeater.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,16 @@ export class Repeater extends CustomLayoutView implements RepeaterDefinition {
102102

103103
public onLayout(left: number, top: number, right: number, bottom: number): void {
104104
const insets = this.getSafeAreaInsets();
105-
const childLeft = left + insets.left;
106-
const childTop = top + insets.top;
107-
const childRight = right - insets.right;
108-
const childBottom = bottom - insets.bottom;
105+
106+
const paddingLeft = this.effectiveBorderLeftWidth + this.effectivePaddingLeft + insets.left;
107+
const paddingTop = this.effectiveBorderTopWidth + this.effectivePaddingTop + insets.top;
108+
const paddingRight = this.effectiveBorderRightWidth + this.effectivePaddingRight + insets.right;
109+
const paddingBottom = this.effectiveBorderBottomWidth + this.effectivePaddingBottom + insets.bottom;
110+
111+
const childLeft = paddingLeft;
112+
const childTop = paddingTop;
113+
const childRight = right - left - paddingRight;
114+
const childBottom = bottom - top - paddingBottom;
109115
View.layoutChild(this, this.itemsLayout, childLeft, childTop, childRight, childBottom);
110116
}
111117

0 commit comments

Comments
 (0)