mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
fix(core): ScrollView event wiring sequencing improvement (#10178)
This commit is contained in:
@@ -118,58 +118,6 @@ export class ScrollView extends ScrollViewBase {
|
||||
this.nativeViewProtected.setId(this._androidViewId);
|
||||
}
|
||||
|
||||
protected addNativeListener() {
|
||||
if (!this.nativeViewProtected) {
|
||||
return;
|
||||
}
|
||||
const that = new WeakRef(this);
|
||||
if (this.orientation === 'vertical') {
|
||||
this.scrollChangeHandler = new androidx.core.widget.NestedScrollView.OnScrollChangeListener({
|
||||
onScrollChange(view, scrollX, scrollY) {
|
||||
const owner: ScrollView = that?.get();
|
||||
if (owner) {
|
||||
owner.notify({
|
||||
object: owner,
|
||||
eventName: ScrollView.scrollEvent,
|
||||
scrollX: layout.toDeviceIndependentPixels(scrollX),
|
||||
scrollY: layout.toDeviceIndependentPixels(scrollY),
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
this.nativeViewProtected.setOnScrollChangeListener(this.scrollChangeHandler);
|
||||
} else {
|
||||
this.handler = new android.view.ViewTreeObserver.OnScrollChangedListener({
|
||||
onScrollChanged: function () {
|
||||
const owner: ScrollView = that?.get();
|
||||
if (owner) {
|
||||
owner._onScrollChanged();
|
||||
}
|
||||
},
|
||||
});
|
||||
this.nativeViewProtected.getViewTreeObserver().addOnScrollChangedListener(this.handler);
|
||||
}
|
||||
}
|
||||
|
||||
protected removeNativeListener() {
|
||||
if (!this.nativeViewProtected) {
|
||||
return;
|
||||
}
|
||||
if (this.handler) {
|
||||
this.nativeViewProtected?.getViewTreeObserver().removeOnScrollChangedListener(this.handler);
|
||||
this.handler = null;
|
||||
}
|
||||
if (this.scrollChangeHandler) {
|
||||
this.nativeView?.setOnScrollChangeListener(null);
|
||||
this.scrollChangeHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
disposeNativeView() {
|
||||
this.removeNativeListener();
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
public _onOrientationChanged() {
|
||||
if (this.nativeViewProtected) {
|
||||
const parent = this.parent;
|
||||
@@ -180,6 +128,22 @@ export class ScrollView extends ScrollViewBase {
|
||||
}
|
||||
}
|
||||
|
||||
protected attachNative() {
|
||||
if (!this.handler) {
|
||||
const that = new WeakRef(this);
|
||||
this.handler = new android.view.ViewTreeObserver.OnScrollChangedListener({
|
||||
onScrollChanged: function () {
|
||||
const owner: ScrollView = that.get();
|
||||
if (owner) {
|
||||
owner._onScrollChanged();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
this.nativeViewProtected.getViewTreeObserver().addOnScrollChangedListener(this.handler);
|
||||
}
|
||||
}
|
||||
|
||||
private _lastScrollX = -1;
|
||||
private _lastScrollY = -1;
|
||||
private _onScrollChanged() {
|
||||
@@ -201,6 +165,11 @@ export class ScrollView extends ScrollViewBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected dettachNative() {
|
||||
this.nativeViewProtected.getViewTreeObserver().removeOnScrollChangedListener(this.handler);
|
||||
this.handler = null;
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView.prototype.recycleNativeView = 'never';
|
||||
|
||||
@@ -50,26 +50,11 @@ export class ScrollView extends ScrollViewBase {
|
||||
}
|
||||
|
||||
disposeNativeView() {
|
||||
this.removeNativeListener();
|
||||
this.dettachNative();
|
||||
this._delegate = null;
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
protected addNativeListener() {
|
||||
if (!this.nativeViewProtected) {
|
||||
return;
|
||||
}
|
||||
this._delegate = UIScrollViewDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.nativeViewProtected.delegate = this._delegate;
|
||||
}
|
||||
|
||||
protected removeNativeListener() {
|
||||
if (!this.nativeViewProtected) {
|
||||
return;
|
||||
}
|
||||
this.nativeViewProtected.delegate = null;
|
||||
}
|
||||
|
||||
_setNativeClipToBounds() {
|
||||
if (!this.nativeViewProtected) {
|
||||
return;
|
||||
@@ -78,6 +63,19 @@ export class ScrollView extends ScrollViewBase {
|
||||
this.nativeViewProtected.clipsToBounds = true;
|
||||
}
|
||||
|
||||
protected attachNative() {
|
||||
if (!this._delegate) {
|
||||
this._delegate = UIScrollViewDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
this.nativeViewProtected.delegate = this._delegate;
|
||||
}
|
||||
}
|
||||
|
||||
protected dettachNative() {
|
||||
if (this.nativeViewProtected) {
|
||||
this.nativeViewProtected.delegate = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected updateScrollBarVisibility(value) {
|
||||
if (!this.nativeViewProtected) {
|
||||
return;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { CoreTypes } from '../../core-types';
|
||||
|
||||
@CSSType('ScrollView')
|
||||
export abstract class ScrollViewBase extends ContentView implements ScrollViewDefinition {
|
||||
private _addedScrollEvent = false;
|
||||
private _scrollChangeCount = 0;
|
||||
public static scrollEvent = 'scroll';
|
||||
|
||||
public orientation: CoreTypes.OrientationType;
|
||||
@@ -19,27 +19,51 @@ export abstract class ScrollViewBase extends ContentView implements ScrollViewDe
|
||||
public addEventListener(arg: string, callback: any, thisArg?: any) {
|
||||
super.addEventListener(arg, callback, thisArg);
|
||||
|
||||
if (arg === ScrollViewBase.scrollEvent && !this._addedScrollEvent) {
|
||||
this._addedScrollEvent = true;
|
||||
this.addNativeListener();
|
||||
if (arg === ScrollViewBase.scrollEvent) {
|
||||
this._scrollChangeCount++;
|
||||
this.attach();
|
||||
}
|
||||
}
|
||||
|
||||
public removeEventListener(arg: string, callback: any, thisArg?: any) {
|
||||
super.removeEventListener(arg, callback, thisArg);
|
||||
|
||||
if (arg === ScrollViewBase.scrollEvent && this._addedScrollEvent) {
|
||||
this._addedScrollEvent = false;
|
||||
this.removeNativeListener();
|
||||
if (arg === ScrollViewBase.scrollEvent) {
|
||||
this._scrollChangeCount--;
|
||||
this.dettach();
|
||||
}
|
||||
}
|
||||
|
||||
protected addNativeListener() {
|
||||
// implemented per platform
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
|
||||
this.attach();
|
||||
}
|
||||
|
||||
protected removeNativeListener() {
|
||||
// implemented per platform
|
||||
public disposeNativeView() {
|
||||
this.dettach();
|
||||
super.disposeNativeView();
|
||||
}
|
||||
|
||||
private attach() {
|
||||
if (this._scrollChangeCount > 0 && this.isLoaded) {
|
||||
this.attachNative();
|
||||
}
|
||||
}
|
||||
|
||||
private dettach() {
|
||||
if (this._scrollChangeCount === 0 && this.isLoaded) {
|
||||
this.dettachNative();
|
||||
}
|
||||
}
|
||||
|
||||
protected attachNative() {
|
||||
//
|
||||
}
|
||||
|
||||
protected dettachNative() {
|
||||
//
|
||||
}
|
||||
|
||||
get horizontalOffset(): number {
|
||||
|
||||
Reference in New Issue
Block a user