diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 3a8e4513db9900..e0692d80db130f 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6025,6 +6025,7 @@ public abstract interface class com/facebook/react/views/scroll/VirtualView { public final class com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout : androidx/swiperefreshlayout/widget/SwipeRefreshLayout { public fun (Lcom/facebook/react/bridge/ReactContext;)V public fun canChildScrollUp ()Z + public fun dispatchGenericMotionEvent (Landroid/view/MotionEvent;)Z public fun onInterceptTouchEvent (Landroid/view/MotionEvent;)Z public fun onLayout (ZIIII)V public fun onTouchEvent (Landroid/view/MotionEvent;)Z diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.kt index 7574af95151106..59ae7dbb5e282f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.kt @@ -16,7 +16,13 @@ import com.facebook.react.uimanager.PixelUtil import com.facebook.react.uimanager.events.NativeGestureUtil import kotlin.math.abs -/** Basic extension of [SwipeRefreshLayout] with ReactNative-specific functionality. */ +/** + * Basic extension of [SwipeRefreshLayout] with ReactNative-specific functionality. + * + * This component wraps a scrollable child (typically a ScrollView or RecyclerView) and provides + * pull-to-refresh functionality. It handles touch event interception for the refresh gesture while + * properly forwarding other events to its children. + */ public class ReactSwipeRefreshLayout(reactContext: ReactContext) : SwipeRefreshLayout(reactContext) { @@ -127,6 +133,28 @@ public class ReactSwipeRefreshLayout(reactContext: ReactContext) : return true } + /** + * Dispatches generic motion events to children. + * + * This override ensures that [MotionEvent.ACTION_SCROLL] events (from joystick, scrollwheel, or + * other pointing devices) are properly forwarded to child views. + */ + public override fun dispatchGenericMotionEvent(ev: MotionEvent): Boolean { + // For ACTION_SCROLL events, dispatch to child for handling + // The child ScrollView will use nested scrolling APIs to communicate with this + // SwipeRefreshLayout + if (ev.actionMasked == MotionEvent.ACTION_SCROLL) { + val child = getChildAt(0) + if (child != null) { + val handled = child.dispatchGenericMotionEvent(ev) + if (handled) { + return true + } + } + } + return super.dispatchGenericMotionEvent(ev) + } + private companion object { private const val DEFAULT_CIRCLE_TARGET = 64f }