mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +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
@@ -61,6 +61,7 @@ export function PseudoClassHandler(...pseudoClasses: string[]): MethodDecorator
|
||||
export const _rootModalViews = new Array<ViewBase>();
|
||||
|
||||
export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
public static layoutChangedEvent = "layoutChanged";
|
||||
public static shownModallyEvent = "shownModally";
|
||||
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() {
|
||||
const args: ShownModallyData = {
|
||||
eventName: ViewCommon.shownModallyEvent,
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
ViewCommon, layout, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty,
|
||||
traceEnabled, traceWrite, traceCategories, traceNotifyEvent,
|
||||
paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty,
|
||||
Color
|
||||
Color, EventData
|
||||
} from "./view-common";
|
||||
|
||||
import {
|
||||
@@ -229,6 +229,8 @@ export class View extends ViewCommon {
|
||||
private _isClickable: boolean;
|
||||
private touchListenerIsSet: boolean;
|
||||
private touchListener: android.view.View.OnTouchListener;
|
||||
private layoutChangeListenerIsSet: boolean;
|
||||
private layoutChangeListener: android.view.View.OnLayoutChangeListener;
|
||||
private _manager: android.app.FragmentManager;
|
||||
|
||||
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 {
|
||||
let manager = this._manager;
|
||||
if (!manager) {
|
||||
@@ -305,6 +327,19 @@ export class View extends ViewCommon {
|
||||
public initNativeView(): void {
|
||||
super.initNativeView();
|
||||
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() {
|
||||
@@ -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 {
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -28,6 +28,7 @@ export class View extends ViewCommon {
|
||||
nativeViewProtected: UIView;
|
||||
viewController: UIViewController;
|
||||
|
||||
private _isLaidOut = false;
|
||||
private _hasTransfrom = false;
|
||||
private _privateFlags: number = PFLAG_LAYOUT_REQUIRED | PFLAG_FORCE_LAYOUT;
|
||||
private _cachedFrame: CGRect;
|
||||
@@ -160,6 +161,11 @@ export class View extends ViewCommon {
|
||||
|
||||
const boundsOrigin = nativeView.bounds.origin;
|
||||
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