Emit scroll events on overscroll and fix sticky header

Summary:
Sticky headers (via OCScrollTrackerStickyHeader) did not work with RN because overscroll does not trigger onScroll events.

This diff adds a listener to overscroll, which then emits scroll events.

Changelog:
[Internal][Changed] - Changed ScrollEvent's scrollX and scrollY to float

 ---

# Context

GamingActivity headers are part of the FlatList; on overscroll (when you scroll up when you're already at the top of the FlatList), the header is translated via Animated's native event. The problem on RN is that onScroll is not fired during overscroll (due to how overscroll-decor works - it merely applies a translation on the scroll view itself).

Scroll events propagate to the native animated events as follows:
- ReactScrollView.onScrollChanged -> ReactScrollViewHelper.updateStateOnScrollChanged -> ReactScrollViewHelper.emitScrollEvent -> EventDispatcher.dispatchEvent -> NativeAnimatedNodesManager.onEventDispatch

# Approaches

Two approaches were considered to fix sticky headers:
- [Implemented in this diff] Attach a listener on OverScrollDecor and fire onScroll events. I ran into 2 main issues with this:
  - The header clips as the scroll view is translated down. This is fixed via setting clipChildren.
- Move headers out of FlatList, and translate the header only for positive scroll offsets.
  - Requires product-side code changes
  - Hover outline is cut off by the header
  - Click-drag to scroll does not work on the header

Reviewed By: javache

Differential Revision: D34696042

fbshipit-source-id: 15450f31a7042ce67cdffc74614f4f7b9684d0ca
This commit is contained in:
Genki Kondo
2022-03-15 10:55:08 -07:00
committed by Facebook GitHub Bot
parent 5d560ca99f
commit 289c7f7180
@@ -23,10 +23,10 @@ public class ScrollEvent extends Event<ScrollEvent> {
private static final Pools.SynchronizedPool<ScrollEvent> EVENTS_POOL =
new Pools.SynchronizedPool<>(3);
private int mScrollX;
private int mScrollY;
private double mXVelocity;
private double mYVelocity;
private float mScrollX;
private float mScrollY;
private float mXVelocity;
private float mYVelocity;
private int mContentWidth;
private int mContentHeight;
private int mScrollViewWidth;
@@ -37,8 +37,8 @@ public class ScrollEvent extends Event<ScrollEvent> {
public static ScrollEvent obtain(
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
float scrollX,
float scrollY,
float xVelocity,
float yVelocity,
int contentWidth,
@@ -63,8 +63,8 @@ public class ScrollEvent extends Event<ScrollEvent> {
int surfaceId,
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
float scrollX,
float scrollY,
float xVelocity,
float yVelocity,
int contentWidth,
@@ -107,8 +107,8 @@ public class ScrollEvent extends Event<ScrollEvent> {
int surfaceId,
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
float scrollX,
float scrollY,
float xVelocity,
float yVelocity,
int contentWidth,