Skip to content

Commit 809842b

Browse files
committed
feat: scrollStart event
Also scroll and scrollStart events now have dx and dy values representing the scroll direction since the last event
1 parent 2303930 commit 809842b

File tree

3 files changed

+66
-35
lines changed

3 files changed

+66
-35
lines changed

src/collectionview/collectionview-common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export abstract class CollectionViewBase extends View implements CollectionViewD
9696
public static itemLoadingEvent = 'itemLoading';
9797
// public static cellCreateEvent = 'cellCreate';
9898
public static scrollEvent = 'scroll';
99+
public static scrollStartEvent = 'scrollStart';
99100
public static scrollEndEvent = 'scrollEnd';
100101
public static itemTapEvent = 'itemTap';
101102
public static displayItemEvent = 'displayItem';

src/collectionview/collectionview.android.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ export class CollectionView extends CollectionViewBase {
216216
private _scrollOrLoadMoreChangeCount = 0;
217217
private _nScrollListener: com.nativescript.collectionview.OnScrollListener.Listener;
218218
scrolling = false;
219+
needsScrollStartEvent = false;
219220

220221
private _hlayoutParams: android.view.ViewGroup.LayoutParams;
221222
private _vlayoutParams: android.view.ViewGroup.LayoutParams;
@@ -360,22 +361,34 @@ export class CollectionView extends CollectionViewBase {
360361
}
361362
}
362363
}
364+
private computeScrollEventData(view: androidx.recyclerview.widget.RecyclerView, eventName: string, dx?: number, dy?: number) {
365+
const horizontal = this.isHorizontal();
366+
const offset = horizontal ? view.computeHorizontalScrollOffset() : view.computeVerticalScrollOffset();
367+
const range = horizontal ? view.computeHorizontalScrollRange() : view.computeVerticalScrollRange();
368+
const extent = horizontal ? view.computeHorizontalScrollExtent() : view.computeVerticalScrollExtent();
369+
return {
370+
object: this,
371+
eventName,
372+
scrollOffset: offset / layout.getDisplayDensity(),
373+
scrollOffsetPercentage: offset / (range - extent),
374+
dx,
375+
dy
376+
};
377+
}
363378

364379
public onScrolled(view: androidx.recyclerview.widget.RecyclerView, dx: number, dy: number) {
365380
if (!this || !this.scrolling) {
366381
return;
367382
}
383+
if (this.needsScrollStartEvent) {
384+
this.needsScrollStartEvent = false;
385+
if (this.hasListeners(CollectionViewBase.scrollStartEvent)) {
386+
this.notify(this.computeScrollEventData(view, CollectionViewBase.scrollStartEvent, dx, dy));
387+
}
388+
}
368389

369390
if (this.hasListeners(CollectionViewBase.scrollEvent)) {
370-
const offset = this.isHorizontal() ? view.computeHorizontalScrollOffset() : view.computeVerticalScrollOffset();
371-
const range = view.computeHorizontalScrollRange();
372-
const extent = view.computeHorizontalScrollExtent();
373-
this.notify({
374-
object: this,
375-
eventName: CollectionViewBase.scrollEvent,
376-
scrollOffset: offset / layout.getDisplayDensity(),
377-
scrollOffsetPercentage: offset / (range - extent)
378-
});
391+
this.notify(this.computeScrollEventData(view, CollectionViewBase.scrollEvent, dx, dy));
379392
}
380393

381394
if (this.hasListeners(CollectionViewBase.loadMoreItemsEvent) && this.items) {
@@ -415,25 +428,18 @@ export class CollectionView extends CollectionViewBase {
415428
this.scrolling = false;
416429

417430
if (this.hasListeners(CollectionViewBase.scrollEndEvent)) {
418-
const offset = this.isHorizontal() ? view.computeHorizontalScrollOffset() : view.computeVerticalScrollOffset();
419-
const range = view.computeHorizontalScrollRange();
420-
const extent = view.computeHorizontalScrollExtent();
421-
this.notify({
422-
object: this,
423-
eventName: CollectionViewBase.scrollEndEvent,
424-
scrollOffset: offset / layout.getDisplayDensity(),
425-
scrollOffsetPercentage: offset / (range - extent)
426-
});
431+
this.notify(this.computeScrollEventData(view, CollectionViewBase.scrollEndEvent));
427432
}
428433
} else if (!this.scrolling && newState === 1) {
429434
//SCROLL_STATE_DRAGGING
435+
this.needsScrollStartEvent = true;
430436
this.scrolling = true;
431437
}
432438
}
433439

434440
public addEventListener(arg: string, callback: any, thisArg?: any) {
435441
super.addEventListener(arg, callback, thisArg);
436-
if (arg === CollectionViewBase.scrollEvent || arg === CollectionViewBase.loadMoreItemsEvent) {
442+
if (arg === CollectionViewBase.scrollEvent || arg === CollectionViewBase.scrollStartEvent || arg === CollectionViewBase.scrollEndEvent || arg === CollectionViewBase.loadMoreItemsEvent) {
437443
this._scrollOrLoadMoreChangeCount++;
438444
this.attachScrollListener();
439445
}
@@ -442,7 +448,7 @@ export class CollectionView extends CollectionViewBase {
442448
public removeEventListener(arg: string, callback: any, thisArg?: any) {
443449
super.removeEventListener(arg, callback, thisArg);
444450

445-
if (arg === CollectionViewBase.scrollEvent || arg === CollectionViewBase.loadMoreItemsEvent) {
451+
if (arg === CollectionViewBase.scrollEvent || arg === CollectionViewBase.scrollStartEvent || arg === CollectionViewBase.scrollEndEvent || arg === CollectionViewBase.loadMoreItemsEvent) {
446452
this._scrollOrLoadMoreChangeCount--;
447453
this.dettachScrollListener();
448454
}

src/collectionview/collectionview.ios.ts

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export class CollectionView extends CollectionViewBase {
103103
});
104104
view.autoresizesSubviews = false;
105105
view.autoresizingMask = UIViewAutoresizing.None;
106+
this.lastContentOffset = view.contentOffset;
106107

107108
return view;
108109
}
@@ -885,25 +886,42 @@ export class CollectionView extends CollectionViewBase {
885886
}
886887
return CGSizeZero;
887888
}
888-
scrollViewDidScroll(scrollView: UIScrollView): void {
889-
const offset = this.isHorizontal() ? scrollView.contentOffset.x : scrollView.contentOffset.y;
890-
const size = this.isHorizontal() ? scrollView.contentSize.width - scrollView.bounds.size.width : scrollView.contentSize.height - scrollView.bounds.size.height;
891-
this.notify({
889+
890+
private computeScrollEventData(scrollView: UIScrollView, eventName: string, dx?: number, dy?: number) {
891+
const horizontal = this.isHorizontal();
892+
const safeAreaInsetsTop = this.iosIgnoreSafeArea ? 0 : scrollView.safeAreaInsets.top;
893+
const offset = horizontal ? scrollView.contentOffset.x : scrollView.contentOffset.y + safeAreaInsetsTop;
894+
const size = horizontal ? scrollView.contentSize.width - scrollView.bounds.size.width : scrollView.contentSize.height - scrollView.bounds.size.height + safeAreaInsetsTop;
895+
return {
892896
object: this,
893-
eventName: CollectionViewBase.scrollEvent,
897+
eventName,
894898
scrollOffset: offset,
895-
scrollOffsetPercentage: offset / size
896-
});
899+
scrollOffsetPercentage: offset / size,
900+
dx,
901+
dy: dy + safeAreaInsetsTop
902+
};
903+
}
904+
lastContentOffset: CGPoint;
905+
needsScrollStartEvent = false;
906+
scrollViewWillBeginDragging(scrollView: UIScrollView): void {
907+
this.lastContentOffset = scrollView.contentOffset;
908+
this.needsScrollStartEvent = true;
909+
}
910+
scrollViewDidScroll(scrollView: UIScrollView): void {
911+
const contentOffset = scrollView.contentOffset;
912+
const dx = contentOffset.x - this.lastContentOffset.x;
913+
const dy = contentOffset.y - this.lastContentOffset.y;
914+
this.lastContentOffset = scrollView.contentOffset;
915+
if (this.needsScrollStartEvent) {
916+
this.needsScrollStartEvent = false;
917+
if (this.hasListeners(CollectionViewBase.scrollStartEvent)) {
918+
this.notify(this.computeScrollEventData(scrollView, CollectionViewBase.scrollStartEvent, dx, dy));
919+
}
920+
}
921+
this.notify(this.computeScrollEventData(scrollView, CollectionViewBase.scrollEvent, dx, dy));
897922
}
898923
scrollViewDidEndDecelerating(scrollView: UIScrollView) {
899-
const offset = this.isHorizontal() ? scrollView.contentOffset.x : scrollView.contentOffset.y;
900-
const size = this.isHorizontal() ? scrollView.contentSize.width - scrollView.bounds.size.width : scrollView.contentSize.height - scrollView.bounds.size.height;
901-
this.notify({
902-
object: this,
903-
eventName: CollectionViewBase.scrollEndEvent,
904-
scrollOffset: offset,
905-
scrollOffsetPercentage: offset / size
906-
});
924+
this.notify(this.computeScrollEventData(scrollView, CollectionViewBase.scrollEndEvent));
907925
}
908926
scrollViewWillEndDraggingWithVelocityTargetContentOffset?(scrollView: UIScrollView, velocity: CGPoint, targetContentOffset: interop.Pointer | interop.Reference<CGPoint>): void {
909927
// this.notify({
@@ -1039,6 +1057,12 @@ class UICollectionViewDelegateImpl extends NSObject implements UICollectionViewD
10391057
owner.scrollViewDidScroll(scrollView);
10401058
}
10411059
}
1060+
scrollViewWillBeginDragging(scrollView: UIScrollView): void {
1061+
const owner = this._owner.get();
1062+
if (owner) {
1063+
owner.scrollViewWillBeginDragging(scrollView);
1064+
}
1065+
}
10421066
scrollViewDidEndDecelerating(scrollView: UIScrollView) {
10431067
const owner = this._owner.get();
10441068
if (owner) {

0 commit comments

Comments
 (0)