Allow Java classes to hook into ScrollView scroll and layout events

Summary:
For advanced interop cases.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D23984345

fbshipit-source-id: f5c2a43a1bf5937f9974bcc5c66c36ec35e679c5
This commit is contained in:
Joshua Gross
2020-09-29 13:16:57 -07:00
committed by Facebook GitHub Bot
parent 5ccb5f5b80
commit c06f765f7d
3 changed files with 33 additions and 0 deletions
@@ -266,6 +266,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
int scrollToY =
pendingContentOffsetY != UNSET_CONTENT_OFFSET ? pendingContentOffsetY : getScrollY();
reactScrollTo(scrollToX, scrollToY);
ReactScrollViewHelper.emitLayoutEvent(this);
}
/**
@@ -223,6 +223,7 @@ public class ReactScrollView extends ScrollView
int scrollToY =
pendingContentOffsetY != UNSET_CONTENT_OFFSET ? pendingContentOffsetY : getScrollY();
reactScrollTo(scrollToX, scrollToY);
ReactScrollViewHelper.emitLayoutEvent(this);
}
@Override
@@ -14,6 +14,8 @@ import android.widget.OverScroller;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.UIManagerHelper;
import java.util.ArrayList;
import java.util.List;
/** Helper class that deals with emitting Scroll Events. */
public class ReactScrollViewHelper {
@@ -23,6 +25,16 @@ public class ReactScrollViewHelper {
public static final String AUTO = "auto";
public static final String OVER_SCROLL_NEVER = "never";
public interface ScrollListener {
void onScroll(
ViewGroup scrollView, ScrollEventType scrollEventType, float xVelocity, float yVelocity);
void onLayout(ViewGroup scrollView);
}
// Support global native listeners for scroll events
private static List<ScrollListener> sScrollListeners = new ArrayList<>();
// If all else fails, this is the hardcoded value in OverScroller.java, in AOSP.
// The default is defined here (as of this diff):
// https://android.googlesource.com/platform/frameworks/base/+/ae5bcf23b5f0875e455790d6af387184dbd009c1/core/java/android/widget/OverScroller.java#44
@@ -64,6 +76,10 @@ public class ReactScrollViewHelper {
return;
}
for (ScrollListener scrollListener : sScrollListeners) {
scrollListener.onScroll(scrollView, scrollEventType, xVelocity, yVelocity);
}
ReactContext reactContext = (ReactContext) scrollView.getContext();
UIManagerHelper.getEventDispatcherForReactTag(reactContext, scrollView.getId())
.dispatchEvent(
@@ -80,6 +96,13 @@ public class ReactScrollViewHelper {
scrollView.getHeight()));
}
/** This is only for Java listeners. onLayout events emitted to JS are handled elsewhere. */
public static void emitLayoutEvent(ViewGroup scrollView) {
for (ScrollListener scrollListener : sScrollListeners) {
scrollListener.onLayout(scrollView);
}
}
public static int parseOverScrollMode(String jsOverScrollMode) {
if (jsOverScrollMode == null || jsOverScrollMode.equals(AUTO)) {
return View.OVER_SCROLL_IF_CONTENT_SCROLLS;
@@ -130,4 +153,12 @@ public class ReactScrollViewHelper {
mScrollAnimationDuration = duration;
}
}
public static void addScrollListener(ScrollListener listener) {
sScrollListeners.add(listener);
}
public static void removeScrollListener(ScrollListener listener) {
sScrollListeners.remove(listener);
}
}