FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat(view): introduce LayoutChanged event on every View component (#… · NativeScript/NativeScript@0fc1547 · GitHub

Commit 0fc1547

Browse files
authored
feat(view): introduce LayoutChanged event on every View component (#5825)
* feat(view): introduce LayoutChanged event * test(view): add LayoutChanged event tests * chore(view-android): attach to onLayoutChange only if listener attached * feat(view-android): override on/off in order to attach and detach from OnLayoutChangeListener
1 parent f671f77 commit 0fc1547

8 files changed

Lines changed: 305 additions & 18 deletions

File tree

‎tests/app/testRunner.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ allTests["FRAME"] = frameTests;
141141
import * as viewTests from "./ui/view/view-tests";
142142
allTests["VIEW"] = viewTests;
143143

144+
import * as viewLayoutChangedEventTests from "./ui/view/view-tests-layout-event";
145+
allTests["VIEW-LAYOUT-EVENT"] = viewLayoutChangedEventTests;
146+
144147
import * as styleTests from "./ui/styling/style-tests";
145148
allTests["STYLE"] = styleTests;
146149

‎tests/app/ui/helper.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export function getColor(uiColor: UIColor): Color {
3737
return new Color(alpha, red, green, blue);
3838
}
3939

40-
function clearPage(): void {
40+
export function clearPage(): void {
4141
let newPage = getCurrentPage();
4242
if (!newPage) {
4343
throw new Error("NO CURRENT PAGE!!!!");
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
import * as commonTests from "./view-tests-common";
2+
3+
import { View } from "tns-core-modules/ui/core/view";
4+
import { Button } from "tns-core-modules/ui/button";
5+
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout/stack-layout";
6+
import * as helper from "../helper";
7+
import * as TKUnit from "../../TKUnit";
8+
import * as utils from "tns-core-modules/utils/utils";
9+
10+
export function test_event_LayoutChanged_GetActualSize() {
11+
const test = function (views: Array<View>) {
12+
let buttonLayoutChanged = false;
13+
14+
views[1].on(View.layoutChangedEvent, (data) => {
15+
buttonLayoutChanged = true;
16+
});
17+
18+
TKUnit.waitUntilReady(() => buttonLayoutChanged);
19+
TKUnit.assert(views[1].getActualSize().height > 0);
20+
TKUnit.assert(views[1].getActualSize().width > 0);
21+
};
22+
23+
helper.do_PageTest_WithStackLayout_AndButton(test);
24+
};
25+
26+
export function test_event_LayoutChanged_Listeners() {
27+
const test = function (views: Array<View>) {
28+
let stackLayoutChanged = false;
29+
let buttonLayoutChanged = false;
30+
31+
views[1].on(View.layoutChangedEvent, (data) => {
32+
buttonLayoutChanged = true;
33+
});
34+
35+
TKUnit.waitUntilReady(() => buttonLayoutChanged);
36+
TKUnit.assertFalse(views[0].hasListeners(View.layoutChangedEvent));
37+
TKUnit.assert(views[1].hasListeners(View.layoutChangedEvent));
38+
};
39+
40+
helper.do_PageTest_WithStackLayout_AndButton(test);
41+
};
42+
43+
export function test_event_LayoutChanged_IsRaised() {
44+
helper.clearPage();
45+
let newPage = helper.getCurrentPage();
46+
47+
let stackLayoutChanged = false;
48+
let buttonLayoutChanged = false;
49+
50+
let stackLayout = new StackLayout();
51+
let button = new Button();
52+
53+
stackLayout.on(View.layoutChangedEvent, (data) => {
54+
stackLayoutChanged = true;
55+
});
56+
57+
button.on(View.layoutChangedEvent, (data) => {
58+
buttonLayoutChanged = true;
59+
});
60+
61+
stackLayout.addChild(button);
62+
newPage.content = stackLayout;
63+
64+
TKUnit.waitUntilReady(() => stackLayoutChanged && buttonLayoutChanged);
65+
TKUnit.assert(stackLayoutChanged);
66+
TKUnit.assert(buttonLayoutChanged);
67+
68+
newPage.content = null;
69+
};
70+
71+
export function test_event_LayoutChanged_IsRaised_StackLayout_ChildAdded() {
72+
helper.clearPage();
73+
let newPage = helper.getCurrentPage();
74+
75+
let stackLayoutChangedCount = 0;
76+
let button1LayoutChangedCount = 0;
77+
let button2LayoutChanged = false;
78+
79+
let stackLayout = new StackLayout();
80+
81+
// StackLayout should not be stretched in order to layout again when new button added.
82+
stackLayout.verticalAlignment = "top";
83+
let button1 = new Button();
84+
let button2 = new Button();
85+
86+
stackLayout.on(View.layoutChangedEvent, (data) => {
87+
stackLayoutChangedCount++;
88+
});
89+
90+
button1.on(View.layoutChangedEvent, (data) => {
91+
button1LayoutChangedCount++;
92+
});
93+
94+
button2.on(View.layoutChangedEvent, (data) => {
95+
button2LayoutChanged = true;
96+
});
97+
98+
stackLayout.addChild(button1);
99+
newPage.content = stackLayout;
100+
101+
TKUnit.waitUntilReady(() => stackLayout.isLoaded);
102+
stackLayout.addChild(button2);
103+
104+
TKUnit.waitUntilReady(() => button2LayoutChanged);
105+
TKUnit.assertEqual(stackLayoutChangedCount, 2);
106+
TKUnit.assertEqual(button1LayoutChangedCount, 1);
107+
TKUnit.assert(button2LayoutChanged);
108+
109+
newPage.content = null;
110+
};
111+
112+
export function test_event_LayoutChanged_IsRaised_ChildMarginChanged() {
113+
const test = function (views: Array<View>) {
114+
let stackLayoutChanged = false;
115+
let buttonLayoutChanged = false;
116+
117+
views[1].on(View.layoutChangedEvent, (data) => {
118+
stackLayoutChanged = true;
119+
});
120+
121+
views[2].on(View.layoutChangedEvent, (data) => {
122+
buttonLayoutChanged = true;
123+
});
124+
125+
(<Button>views[2]).marginTop = 50;
126+
127+
TKUnit.waitUntilReady(() => buttonLayoutChanged);
128+
129+
TKUnit.assert(stackLayoutChanged);
130+
TKUnit.assert(buttonLayoutChanged);
131+
};
132+
133+
helper.do_PageTest_WithStackLayout_AndButton(test);
134+
};
135+
136+
export function test_event_LayoutChanged_IsRaised_ParentMarginChanged() {
137+
const test = function (views: Array<View>) {
138+
let stackLayoutChanged = false;
139+
let buttonLayoutChanged = false;
140+
141+
views[1].on(View.layoutChangedEvent, (data) => {
142+
stackLayoutChanged = true;
143+
});
144+
145+
views[2].on(View.layoutChangedEvent, (data) => {
146+
buttonLayoutChanged = true;
147+
});
148+
149+
(<Button>views[2]).marginTop = 50;
150+
151+
TKUnit.waitUntilReady(() => buttonLayoutChanged);
152+
153+
TKUnit.assert(stackLayoutChanged);
154+
TKUnit.assert(buttonLayoutChanged);
155+
};
156+
157+
helper.do_PageTest_WithStackLayout_AndButton(test);
158+
};
159+
160+
export function test_event_LayoutChanged_IsNotRaised_TransformChanged() {
161+
const test = function (views: Array<View>) {
162+
let stackLayoutChangedCount = 0;
163+
let buttonLayoutChangedCount = 0;
164+
const button = <Button>views[2];
165+
166+
views[1].on(View.layoutChangedEvent, (data) => {
167+
stackLayoutChangedCount++;
168+
});
169+
170+
button.on(View.layoutChangedEvent, (data) => {
171+
buttonLayoutChangedCount++;
172+
});
173+
174+
button.translateX += 50;
175+
button.translateY += 50;
176+
button.rotate += 50;
177+
button.height = 200;
178+
179+
TKUnit.waitUntilReady(() => button.height === 200);
180+
181+
TKUnit.assertEqual(stackLayoutChangedCount, 1);
182+
TKUnit.assertEqual(buttonLayoutChangedCount, 1);
183+
};
184+
185+
helper.do_PageTest_WithStackLayout_AndButton(test);
186+
};
187+
188+
export function test_event_LayoutChanged_IsRaised_StackLayout_SizeChanged() {
189+
const test = function (views: Array<View>) {
190+
let stackLayoutChanged = false;
191+
let buttonLayoutChanged = false;
192+
193+
views[1].on(View.layoutChangedEvent, (data) => {
194+
stackLayoutChanged = true;
195+
});
196+
197+
views[2].on(View.layoutChangedEvent, (data) => {
198+
buttonLayoutChanged = true;
199+
});
200+
201+
(<StackLayout>views[1]).height = 100;
202+
203+
TKUnit.waitUntilReady(() => buttonLayoutChanged);
204+
205+
TKUnit.assert(stackLayoutChanged);
206+
TKUnit.assert(buttonLayoutChanged);
207+
};
208+
209+
helper.do_PageTest_WithStackLayout_AndButton(test);
210+
};

‎tests/app/ui/view/view-tests.ios.ts‎

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import * as commonTests from "./view-tests-common";
2-
import * as view from "tns-core-modules/ui/core/view";
3-
import * as grid from "tns-core-modules/ui/layouts/grid-layout";
4-
import * as color from "tns-core-modules/color";
2+
3+
import { View } from "tns-core-modules/ui/core/view";
4+
import { Button } from "tns-core-modules/ui/button";
5+
import { GridLayout } from "tns-core-modules/ui/layouts/grid-layout";
6+
import { Color } from "tns-core-modules/color";
57
import * as helper from "../helper";
68
import * as TKUnit from "../../TKUnit";
7-
import * as button from "tns-core-modules/ui/button";
89
import * as utils from "tns-core-modules/utils/utils";
910

1011
global.moduleMerge(commonTests, exports);
1112

12-
class MyGrid extends grid.GridLayout {
13+
class MyGrid extends GridLayout {
1314
public backgroundDrawCount: number = 0;
1415

1516
_redrawNativeBackground(background: any) {
@@ -18,33 +19,33 @@ class MyGrid extends grid.GridLayout {
1819
}
1920
}
2021

21-
export function getUniformNativeBorderWidth(v: view.View): number {
22+
export function getUniformNativeBorderWidth(v: View): number {
2223
return utils.layout.toDevicePixels((<UIView>v.ios).layer.borderWidth);
2324
}
2425

25-
export function checkUniformNativeBorderColor(v: view.View): boolean {
26-
if (v.borderColor instanceof color.Color) {
27-
return (<UIView>v.ios).layer.borderColor === (<color.Color>v.borderColor).ios.CGColor;
26+
export function checkUniformNativeBorderColor(v: View): boolean {
27+
if (v.borderColor instanceof Color) {
28+
return (<UIView>v.ios).layer.borderColor === (<Color>v.borderColor).ios.CGColor;
2829
}
2930

3031
return undefined;
3132
}
3233

33-
export function getUniformNativeCornerRadius(v: view.View): number {
34+
export function getUniformNativeCornerRadius(v: View): number {
3435
return utils.layout.toDevicePixels((<UIView>v.ios).layer.cornerRadius);
3536
}
3637

37-
export function checkNativeBackgroundColor(v: view.View): boolean {
38+
export function checkNativeBackgroundColor(v: View): boolean {
3839
if (v.ios instanceof UILabel) {
3940
var cgColor1 = (<UILabel>v.ios).layer.backgroundColor;
40-
var cgColor2 = (<UIColor>(<color.Color>v.backgroundColor).ios).CGColor;
41+
var cgColor2 = (<UIColor>(<Color>v.backgroundColor).ios).CGColor;
4142
return v.backgroundColor && !!CGColorEqualToColor(cgColor1, cgColor2);
4243
}
4344

44-
return v.backgroundColor && (<UIView>v.ios).backgroundColor.isEqual((<color.Color>v.backgroundColor).ios);
45+
return v.backgroundColor && (<UIView>v.ios).backgroundColor.isEqual((<Color>v.backgroundColor).ios);
4546
}
4647

47-
export function checkNativeBackgroundImage(v: view.View): boolean {
48+
export function checkNativeBackgroundImage(v: View): boolean {
4849
return (<UIView>v.ios).backgroundColor !== undefined;
4950
}
5051

@@ -53,7 +54,7 @@ export function testBackgroundInternalChangedOnceOnResize() {
5354
let root = helper.getCurrentPage();
5455
let layout = new MyGrid();
5556
layout.className = "myClass";
56-
layout.backgroundColor = new color.Color(255, 255, 0, 0);
57+
layout.backgroundColor = new Color(255, 255, 0, 0);
5758

5859
root.css = ".myClass { background-image: url('~/logo.png') }";
5960
root.content = layout;
@@ -82,7 +83,7 @@ export function testBackgroundInternalChangedOnceOnResize() {
8283
}
8384

8485
export function test_automation_text_set_to_native() {
85-
var newButton = new button.Button();
86+
var newButton = new Button();
8687
newButton.automationText = "Button1";
8788
helper.getCurrentPage().content = newButton;
8889
TKUnit.assertEqual((<UIView>newButton.ios).accessibilityIdentifier, "Button1", "accessibilityIdentifier not set to native view.");

‎tns-core-modules/ui/core/view/view-common.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export function PseudoClassHandler(...pseudoClasses: string[]): MethodDecorator
6161
export const _rootModalViews = new Array<ViewBase>();
6262

6363
export abstract class ViewCommon extends ViewBase implements ViewDefinition {
64+
public static layoutChangedEvent = "layoutChanged";
6465
public static shownModallyEvent = "shownModally";
6566
public static showingModallyEvent = "showingModally";
6667

@@ -277,6 +278,14 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
277278
//
278279
}
279280

281+
protected _raiseLayoutChangedEvent() {
282+
const args: EventData = {
283+
eventName: ViewCommon.layoutChangedEvent,
284+
object: this
285+
};
286+
this.notify(args);
287+
}
288+
280289
protected _raiseShownModallyEvent() {
281290
const args: ShownModallyData = {
282291
eventName: ViewCommon.shownModallyEvent,

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL