mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
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
This commit is contained in:

committed by
GitHub

parent
f671f778f3
commit
0fc1547a19
@ -141,6 +141,9 @@ allTests["FRAME"] = frameTests;
|
|||||||
import * as viewTests from "./ui/view/view-tests";
|
import * as viewTests from "./ui/view/view-tests";
|
||||||
allTests["VIEW"] = viewTests;
|
allTests["VIEW"] = viewTests;
|
||||||
|
|
||||||
|
import * as viewLayoutChangedEventTests from "./ui/view/view-tests-layout-event";
|
||||||
|
allTests["VIEW-LAYOUT-EVENT"] = viewLayoutChangedEventTests;
|
||||||
|
|
||||||
import * as styleTests from "./ui/styling/style-tests";
|
import * as styleTests from "./ui/styling/style-tests";
|
||||||
allTests["STYLE"] = styleTests;
|
allTests["STYLE"] = styleTests;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ export function getColor(uiColor: UIColor): Color {
|
|||||||
return new Color(alpha, red, green, blue);
|
return new Color(alpha, red, green, blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearPage(): void {
|
export function clearPage(): void {
|
||||||
let newPage = getCurrentPage();
|
let newPage = getCurrentPage();
|
||||||
if (!newPage) {
|
if (!newPage) {
|
||||||
throw new Error("NO CURRENT PAGE!!!!");
|
throw new Error("NO CURRENT PAGE!!!!");
|
||||||
|
210
tests/app/ui/view/view-tests-layout-event.ts
Normal file
210
tests/app/ui/view/view-tests-layout-event.ts
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
import * as commonTests from "./view-tests-common";
|
||||||
|
|
||||||
|
import { View } from "tns-core-modules/ui/core/view";
|
||||||
|
import { Button } from "tns-core-modules/ui/button";
|
||||||
|
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout/stack-layout";
|
||||||
|
import * as helper from "../helper";
|
||||||
|
import * as TKUnit from "../../TKUnit";
|
||||||
|
import * as utils from "tns-core-modules/utils/utils";
|
||||||
|
|
||||||
|
export function test_event_LayoutChanged_GetActualSize() {
|
||||||
|
const test = function (views: Array<View>) {
|
||||||
|
let buttonLayoutChanged = false;
|
||||||
|
|
||||||
|
views[1].on(View.layoutChangedEvent, (data) => {
|
||||||
|
buttonLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => buttonLayoutChanged);
|
||||||
|
TKUnit.assert(views[1].getActualSize().height > 0);
|
||||||
|
TKUnit.assert(views[1].getActualSize().width > 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.do_PageTest_WithStackLayout_AndButton(test);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function test_event_LayoutChanged_Listeners() {
|
||||||
|
const test = function (views: Array<View>) {
|
||||||
|
let stackLayoutChanged = false;
|
||||||
|
let buttonLayoutChanged = false;
|
||||||
|
|
||||||
|
views[1].on(View.layoutChangedEvent, (data) => {
|
||||||
|
buttonLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => buttonLayoutChanged);
|
||||||
|
TKUnit.assertFalse(views[0].hasListeners(View.layoutChangedEvent));
|
||||||
|
TKUnit.assert(views[1].hasListeners(View.layoutChangedEvent));
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.do_PageTest_WithStackLayout_AndButton(test);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function test_event_LayoutChanged_IsRaised() {
|
||||||
|
helper.clearPage();
|
||||||
|
let newPage = helper.getCurrentPage();
|
||||||
|
|
||||||
|
let stackLayoutChanged = false;
|
||||||
|
let buttonLayoutChanged = false;
|
||||||
|
|
||||||
|
let stackLayout = new StackLayout();
|
||||||
|
let button = new Button();
|
||||||
|
|
||||||
|
stackLayout.on(View.layoutChangedEvent, (data) => {
|
||||||
|
stackLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
button.on(View.layoutChangedEvent, (data) => {
|
||||||
|
buttonLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
stackLayout.addChild(button);
|
||||||
|
newPage.content = stackLayout;
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => stackLayoutChanged && buttonLayoutChanged);
|
||||||
|
TKUnit.assert(stackLayoutChanged);
|
||||||
|
TKUnit.assert(buttonLayoutChanged);
|
||||||
|
|
||||||
|
newPage.content = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function test_event_LayoutChanged_IsRaised_StackLayout_ChildAdded() {
|
||||||
|
helper.clearPage();
|
||||||
|
let newPage = helper.getCurrentPage();
|
||||||
|
|
||||||
|
let stackLayoutChangedCount = 0;
|
||||||
|
let button1LayoutChangedCount = 0;
|
||||||
|
let button2LayoutChanged = false;
|
||||||
|
|
||||||
|
let stackLayout = new StackLayout();
|
||||||
|
|
||||||
|
// StackLayout should not be stretched in order to layout again when new button added.
|
||||||
|
stackLayout.verticalAlignment = "top";
|
||||||
|
let button1 = new Button();
|
||||||
|
let button2 = new Button();
|
||||||
|
|
||||||
|
stackLayout.on(View.layoutChangedEvent, (data) => {
|
||||||
|
stackLayoutChangedCount++;
|
||||||
|
});
|
||||||
|
|
||||||
|
button1.on(View.layoutChangedEvent, (data) => {
|
||||||
|
button1LayoutChangedCount++;
|
||||||
|
});
|
||||||
|
|
||||||
|
button2.on(View.layoutChangedEvent, (data) => {
|
||||||
|
button2LayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
stackLayout.addChild(button1);
|
||||||
|
newPage.content = stackLayout;
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => stackLayout.isLoaded);
|
||||||
|
stackLayout.addChild(button2);
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => button2LayoutChanged);
|
||||||
|
TKUnit.assertEqual(stackLayoutChangedCount, 2);
|
||||||
|
TKUnit.assertEqual(button1LayoutChangedCount, 1);
|
||||||
|
TKUnit.assert(button2LayoutChanged);
|
||||||
|
|
||||||
|
newPage.content = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function test_event_LayoutChanged_IsRaised_ChildMarginChanged() {
|
||||||
|
const test = function (views: Array<View>) {
|
||||||
|
let stackLayoutChanged = false;
|
||||||
|
let buttonLayoutChanged = false;
|
||||||
|
|
||||||
|
views[1].on(View.layoutChangedEvent, (data) => {
|
||||||
|
stackLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
views[2].on(View.layoutChangedEvent, (data) => {
|
||||||
|
buttonLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
(<Button>views[2]).marginTop = 50;
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => buttonLayoutChanged);
|
||||||
|
|
||||||
|
TKUnit.assert(stackLayoutChanged);
|
||||||
|
TKUnit.assert(buttonLayoutChanged);
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.do_PageTest_WithStackLayout_AndButton(test);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function test_event_LayoutChanged_IsRaised_ParentMarginChanged() {
|
||||||
|
const test = function (views: Array<View>) {
|
||||||
|
let stackLayoutChanged = false;
|
||||||
|
let buttonLayoutChanged = false;
|
||||||
|
|
||||||
|
views[1].on(View.layoutChangedEvent, (data) => {
|
||||||
|
stackLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
views[2].on(View.layoutChangedEvent, (data) => {
|
||||||
|
buttonLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
(<Button>views[2]).marginTop = 50;
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => buttonLayoutChanged);
|
||||||
|
|
||||||
|
TKUnit.assert(stackLayoutChanged);
|
||||||
|
TKUnit.assert(buttonLayoutChanged);
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.do_PageTest_WithStackLayout_AndButton(test);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function test_event_LayoutChanged_IsNotRaised_TransformChanged() {
|
||||||
|
const test = function (views: Array<View>) {
|
||||||
|
let stackLayoutChangedCount = 0;
|
||||||
|
let buttonLayoutChangedCount = 0;
|
||||||
|
const button = <Button>views[2];
|
||||||
|
|
||||||
|
views[1].on(View.layoutChangedEvent, (data) => {
|
||||||
|
stackLayoutChangedCount++;
|
||||||
|
});
|
||||||
|
|
||||||
|
button.on(View.layoutChangedEvent, (data) => {
|
||||||
|
buttonLayoutChangedCount++;
|
||||||
|
});
|
||||||
|
|
||||||
|
button.translateX += 50;
|
||||||
|
button.translateY += 50;
|
||||||
|
button.rotate += 50;
|
||||||
|
button.height = 200;
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => button.height === 200);
|
||||||
|
|
||||||
|
TKUnit.assertEqual(stackLayoutChangedCount, 1);
|
||||||
|
TKUnit.assertEqual(buttonLayoutChangedCount, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.do_PageTest_WithStackLayout_AndButton(test);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function test_event_LayoutChanged_IsRaised_StackLayout_SizeChanged() {
|
||||||
|
const test = function (views: Array<View>) {
|
||||||
|
let stackLayoutChanged = false;
|
||||||
|
let buttonLayoutChanged = false;
|
||||||
|
|
||||||
|
views[1].on(View.layoutChangedEvent, (data) => {
|
||||||
|
stackLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
views[2].on(View.layoutChangedEvent, (data) => {
|
||||||
|
buttonLayoutChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
(<StackLayout>views[1]).height = 100;
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => buttonLayoutChanged);
|
||||||
|
|
||||||
|
TKUnit.assert(stackLayoutChanged);
|
||||||
|
TKUnit.assert(buttonLayoutChanged);
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.do_PageTest_WithStackLayout_AndButton(test);
|
||||||
|
};
|
@ -1,15 +1,16 @@
|
|||||||
import * as commonTests from "./view-tests-common";
|
import * as commonTests from "./view-tests-common";
|
||||||
import * as view from "tns-core-modules/ui/core/view";
|
|
||||||
import * as grid from "tns-core-modules/ui/layouts/grid-layout";
|
import { View } from "tns-core-modules/ui/core/view";
|
||||||
import * as color from "tns-core-modules/color";
|
import { Button } from "tns-core-modules/ui/button";
|
||||||
|
import { GridLayout } from "tns-core-modules/ui/layouts/grid-layout";
|
||||||
|
import { Color } from "tns-core-modules/color";
|
||||||
import * as helper from "../helper";
|
import * as helper from "../helper";
|
||||||
import * as TKUnit from "../../TKUnit";
|
import * as TKUnit from "../../TKUnit";
|
||||||
import * as button from "tns-core-modules/ui/button";
|
|
||||||
import * as utils from "tns-core-modules/utils/utils";
|
import * as utils from "tns-core-modules/utils/utils";
|
||||||
|
|
||||||
global.moduleMerge(commonTests, exports);
|
global.moduleMerge(commonTests, exports);
|
||||||
|
|
||||||
class MyGrid extends grid.GridLayout {
|
class MyGrid extends GridLayout {
|
||||||
public backgroundDrawCount: number = 0;
|
public backgroundDrawCount: number = 0;
|
||||||
|
|
||||||
_redrawNativeBackground(background: any) {
|
_redrawNativeBackground(background: any) {
|
||||||
@ -18,33 +19,33 @@ class MyGrid extends grid.GridLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUniformNativeBorderWidth(v: view.View): number {
|
export function getUniformNativeBorderWidth(v: View): number {
|
||||||
return utils.layout.toDevicePixels((<UIView>v.ios).layer.borderWidth);
|
return utils.layout.toDevicePixels((<UIView>v.ios).layer.borderWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkUniformNativeBorderColor(v: view.View): boolean {
|
export function checkUniformNativeBorderColor(v: View): boolean {
|
||||||
if (v.borderColor instanceof color.Color) {
|
if (v.borderColor instanceof Color) {
|
||||||
return (<UIView>v.ios).layer.borderColor === (<color.Color>v.borderColor).ios.CGColor;
|
return (<UIView>v.ios).layer.borderColor === (<Color>v.borderColor).ios.CGColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUniformNativeCornerRadius(v: view.View): number {
|
export function getUniformNativeCornerRadius(v: View): number {
|
||||||
return utils.layout.toDevicePixels((<UIView>v.ios).layer.cornerRadius);
|
return utils.layout.toDevicePixels((<UIView>v.ios).layer.cornerRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkNativeBackgroundColor(v: view.View): boolean {
|
export function checkNativeBackgroundColor(v: View): boolean {
|
||||||
if (v.ios instanceof UILabel) {
|
if (v.ios instanceof UILabel) {
|
||||||
var cgColor1 = (<UILabel>v.ios).layer.backgroundColor;
|
var cgColor1 = (<UILabel>v.ios).layer.backgroundColor;
|
||||||
var cgColor2 = (<UIColor>(<color.Color>v.backgroundColor).ios).CGColor;
|
var cgColor2 = (<UIColor>(<Color>v.backgroundColor).ios).CGColor;
|
||||||
return v.backgroundColor && !!CGColorEqualToColor(cgColor1, cgColor2);
|
return v.backgroundColor && !!CGColorEqualToColor(cgColor1, cgColor2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.backgroundColor && (<UIView>v.ios).backgroundColor.isEqual((<color.Color>v.backgroundColor).ios);
|
return v.backgroundColor && (<UIView>v.ios).backgroundColor.isEqual((<Color>v.backgroundColor).ios);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkNativeBackgroundImage(v: view.View): boolean {
|
export function checkNativeBackgroundImage(v: View): boolean {
|
||||||
return (<UIView>v.ios).backgroundColor !== undefined;
|
return (<UIView>v.ios).backgroundColor !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ export function testBackgroundInternalChangedOnceOnResize() {
|
|||||||
let root = helper.getCurrentPage();
|
let root = helper.getCurrentPage();
|
||||||
let layout = new MyGrid();
|
let layout = new MyGrid();
|
||||||
layout.className = "myClass";
|
layout.className = "myClass";
|
||||||
layout.backgroundColor = new color.Color(255, 255, 0, 0);
|
layout.backgroundColor = new Color(255, 255, 0, 0);
|
||||||
|
|
||||||
root.css = ".myClass { background-image: url('~/logo.png') }";
|
root.css = ".myClass { background-image: url('~/logo.png') }";
|
||||||
root.content = layout;
|
root.content = layout;
|
||||||
@ -82,7 +83,7 @@ export function testBackgroundInternalChangedOnceOnResize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function test_automation_text_set_to_native() {
|
export function test_automation_text_set_to_native() {
|
||||||
var newButton = new button.Button();
|
var newButton = new Button();
|
||||||
newButton.automationText = "Button1";
|
newButton.automationText = "Button1";
|
||||||
helper.getCurrentPage().content = newButton;
|
helper.getCurrentPage().content = newButton;
|
||||||
TKUnit.assertEqual((<UIView>newButton.ios).accessibilityIdentifier, "Button1", "accessibilityIdentifier not set to native view.");
|
TKUnit.assertEqual((<UIView>newButton.ios).accessibilityIdentifier, "Button1", "accessibilityIdentifier not set to native view.");
|
||||||
|
@ -61,6 +61,7 @@ export function PseudoClassHandler(...pseudoClasses: string[]): MethodDecorator
|
|||||||
export const _rootModalViews = new Array<ViewBase>();
|
export const _rootModalViews = new Array<ViewBase>();
|
||||||
|
|
||||||
export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||||
|
public static layoutChangedEvent = "layoutChanged";
|
||||||
public static shownModallyEvent = "shownModally";
|
public static shownModallyEvent = "shownModally";
|
||||||
public static showingModallyEvent = "showingModally";
|
public static showingModallyEvent = "showingModally";
|
||||||
|
|
||||||
@ -277,6 +278,14 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected _raiseLayoutChangedEvent() {
|
||||||
|
const args: EventData = {
|
||||||
|
eventName: ViewCommon.layoutChangedEvent,
|
||||||
|
object: this
|
||||||
|
};
|
||||||
|
this.notify(args);
|
||||||
|
}
|
||||||
|
|
||||||
protected _raiseShownModallyEvent() {
|
protected _raiseShownModallyEvent() {
|
||||||
const args: ShownModallyData = {
|
const args: ShownModallyData = {
|
||||||
eventName: ViewCommon.shownModallyEvent,
|
eventName: ViewCommon.shownModallyEvent,
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
ViewCommon, layout, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty,
|
ViewCommon, layout, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty,
|
||||||
traceEnabled, traceWrite, traceCategories, traceNotifyEvent,
|
traceEnabled, traceWrite, traceCategories, traceNotifyEvent,
|
||||||
paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty,
|
paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty,
|
||||||
Color
|
Color, EventData
|
||||||
} from "./view-common";
|
} from "./view-common";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -229,6 +229,8 @@ export class View extends ViewCommon {
|
|||||||
private _isClickable: boolean;
|
private _isClickable: boolean;
|
||||||
private touchListenerIsSet: boolean;
|
private touchListenerIsSet: boolean;
|
||||||
private touchListener: android.view.View.OnTouchListener;
|
private touchListener: android.view.View.OnTouchListener;
|
||||||
|
private layoutChangeListenerIsSet: boolean;
|
||||||
|
private layoutChangeListener: android.view.View.OnLayoutChangeListener;
|
||||||
private _manager: android.app.FragmentManager;
|
private _manager: android.app.FragmentManager;
|
||||||
|
|
||||||
nativeViewProtected: android.view.View;
|
nativeViewProtected: android.view.View;
|
||||||
@ -241,6 +243,26 @@ export class View extends ViewCommon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
on(eventNames: string, callback: (data: EventData) => void, thisArg?: any) {
|
||||||
|
super.on(eventNames, callback, thisArg);
|
||||||
|
const isLayoutEvent = typeof eventNames === "string" ? eventNames.indexOf(ViewCommon.layoutChangedEvent) !== -1 : false;
|
||||||
|
|
||||||
|
if (this.isLoaded && !this.layoutChangeListenerIsSet && isLayoutEvent) {
|
||||||
|
this.setOnLayoutChangeListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
off(eventNames: string, callback?: any, thisArg?: any) {
|
||||||
|
super.off(eventNames, callback, thisArg);
|
||||||
|
const isLayoutEvent = typeof eventNames === "string" ? eventNames.indexOf(ViewCommon.layoutChangedEvent) !== -1 : false;
|
||||||
|
|
||||||
|
// Remove native listener only if there are no more user listeners for LayoutChanged event
|
||||||
|
if (this.isLoaded && this.layoutChangeListenerIsSet && isLayoutEvent && !this.hasListeners(ViewCommon.layoutChangedEvent)) {
|
||||||
|
this.nativeViewProtected.removeOnLayoutChangeListener(this.layoutChangeListener);
|
||||||
|
this.layoutChangeListenerIsSet = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public _getFragmentManager(): android.app.FragmentManager {
|
public _getFragmentManager(): android.app.FragmentManager {
|
||||||
let manager = this._manager;
|
let manager = this._manager;
|
||||||
if (!manager) {
|
if (!manager) {
|
||||||
@ -305,6 +327,19 @@ export class View extends ViewCommon {
|
|||||||
public initNativeView(): void {
|
public initNativeView(): void {
|
||||||
super.initNativeView();
|
super.initNativeView();
|
||||||
this._isClickable = this.nativeViewProtected.isClickable();
|
this._isClickable = this.nativeViewProtected.isClickable();
|
||||||
|
|
||||||
|
if (this.hasListeners(ViewCommon.layoutChangedEvent)) {
|
||||||
|
this.setOnLayoutChangeListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public disposeNativeView(): void {
|
||||||
|
super.disposeNativeView();
|
||||||
|
|
||||||
|
if (this.layoutChangeListenerIsSet) {
|
||||||
|
this.layoutChangeListenerIsSet = false;
|
||||||
|
this.nativeViewProtected.removeOnLayoutChangeListener(this.layoutChangeListener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setOnTouchListener() {
|
private setOnTouchListener() {
|
||||||
@ -320,6 +355,25 @@ export class View extends ViewCommon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setOnLayoutChangeListener() {
|
||||||
|
if (this.nativeViewProtected) {
|
||||||
|
const owner = this;
|
||||||
|
this.layoutChangeListenerIsSet = true;
|
||||||
|
this.layoutChangeListener = this.layoutChangeListener || new android.view.View.OnLayoutChangeListener({
|
||||||
|
onLayoutChange(
|
||||||
|
v: android.view.View,
|
||||||
|
left: number, top: number, right: number, bottom: number,
|
||||||
|
oldLeft: number, oldTop: number, oldRight: number, oldBottom: number): void {
|
||||||
|
if (left !== oldLeft || top !== oldTop || right !== oldRight || bottom !== oldBottom) {
|
||||||
|
owner._raiseLayoutChangedEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.nativeViewProtected.addOnLayoutChangeListener(this.layoutChangeListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get isLayoutRequired(): boolean {
|
get isLayoutRequired(): boolean {
|
||||||
return !this.isLayoutValid;
|
return !this.isLayoutValid;
|
||||||
}
|
}
|
||||||
|
4
tns-core-modules/ui/core/view/view.d.ts
vendored
4
tns-core-modules/ui/core/view/view.d.ts
vendored
@ -103,6 +103,10 @@ export interface ShownModallyData extends EventData {
|
|||||||
* A View occupies a rectangular area on the screen and is responsible for drawing and layouting of all UI components within.
|
* A View occupies a rectangular area on the screen and is responsible for drawing and layouting of all UI components within.
|
||||||
*/
|
*/
|
||||||
export abstract class View extends ViewBase {
|
export abstract class View extends ViewBase {
|
||||||
|
/**
|
||||||
|
* String value used when hooking to layoutChanged event.
|
||||||
|
*/
|
||||||
|
public static layoutChangedEvent: string;
|
||||||
/**
|
/**
|
||||||
* String value used when hooking to showingModally event.
|
* String value used when hooking to showingModally event.
|
||||||
*/
|
*/
|
||||||
|
@ -28,6 +28,7 @@ export class View extends ViewCommon {
|
|||||||
nativeViewProtected: UIView;
|
nativeViewProtected: UIView;
|
||||||
viewController: UIViewController;
|
viewController: UIViewController;
|
||||||
|
|
||||||
|
private _isLaidOut = false;
|
||||||
private _hasTransfrom = false;
|
private _hasTransfrom = false;
|
||||||
private _privateFlags: number = PFLAG_LAYOUT_REQUIRED | PFLAG_FORCE_LAYOUT;
|
private _privateFlags: number = PFLAG_LAYOUT_REQUIRED | PFLAG_FORCE_LAYOUT;
|
||||||
private _cachedFrame: CGRect;
|
private _cachedFrame: CGRect;
|
||||||
@ -160,6 +161,11 @@ export class View extends ViewCommon {
|
|||||||
|
|
||||||
const boundsOrigin = nativeView.bounds.origin;
|
const boundsOrigin = nativeView.bounds.origin;
|
||||||
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, frame.size.width, frame.size.height);
|
nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, frame.size.width, frame.size.height);
|
||||||
|
this._raiseLayoutChangedEvent();
|
||||||
|
this._isLaidOut = true;
|
||||||
|
} else if (!this._isLaidOut) {
|
||||||
|
// Rects could be equal on the first layout and an event should be raised.
|
||||||
|
this._raiseLayoutChangedEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user