fix(core): ScrollView event wiring sequencing improvement (#10178)

This commit is contained in:
Nathan Walker
2023-01-19 12:28:56 -08:00
committed by GitHub
parent 7993de51b3
commit 75821ead07
6 changed files with 111 additions and 79 deletions

View File

@@ -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';

View File

@@ -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;

View File

@@ -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 {