diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt index 877d9d7126..163d4d6793 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt @@ -593,6 +593,16 @@ open class GestureHandler { // generated faster than they can be treated by JS thread eventCoalescingKey = nextEventCoalescingKey++ } + + check(hostDetectorView != null || orchestrator != null) { + "Manually handled gesture had not been assigned to any detector" + } + + if (orchestrator == null) { + // If the state is set manually, the handler may not have been fully recorded by the orchestrator. + hostDetectorView?.recordHandlerIfNotPresent(this) + } + orchestrator!!.onHandlerStateChange(this, newState, oldState) onStateChange(newState, oldState) } diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt index 3f13f15b82..5907cd6ac1 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt @@ -442,7 +442,7 @@ class GestureHandlerOrchestrator( } } - private fun recordHandlerIfNotPresent(handler: GestureHandler, view: View) { + fun recordHandlerIfNotPresent(handler: GestureHandler, view: View?) { if (gestureHandlers.contains(handler)) { return } diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt index c57dd8ad37..4d2c98e461 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt @@ -2,6 +2,7 @@ package com.swmansion.gesturehandler.react import android.content.Context import android.view.View +import android.view.ViewParent import com.facebook.react.bridge.ReadableArray import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.UIManagerHelper @@ -202,7 +203,23 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) { child.value.clear() } } + fun recordHandlerIfNotPresent(handler: GestureHandler) { + findGestureHandlerRootView()?.recordHandlerIfNotPresent(handler) + } + + private fun findGestureHandlerRootView(): RNGestureHandlerRootView? { + var parent: ViewParent? = this.parent + var gestureHandlerRootView: RNGestureHandlerRootView? = null + + while (parent != null) { + if (parent is RNGestureHandlerRootView) { + gestureHandlerRootView = parent + } + parent = parent.parent + } + return gestureHandlerRootView + } private fun ReadableArray.mapVirtualChildren(): List = List(size()) { i -> val child = getMap(i) ?: return@List null val handlerTags = child.getArray("handlerTags")?.toIntList().orEmpty() diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt index 131119ecb7..fb327172be 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt @@ -141,6 +141,10 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView: orchestrator?.activateNativeHandlersForView(view) } + fun recordHandlerIfNotPresent(handler: GestureHandler) { + orchestrator?.recordHandlerIfNotPresent(handler, null) + } + companion object { private const val MIN_ALPHA_FOR_TOUCH = 0.1f private fun findRootViewTag(viewGroup: ViewGroup): ViewGroup { diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt index f66bcd8387..670ed5eba8 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt @@ -10,6 +10,7 @@ import com.facebook.react.bridge.UiThreadUtil import com.facebook.react.common.ReactConstants import com.facebook.react.uimanager.RootView import com.facebook.react.views.view.ReactViewGroup +import com.swmansion.gesturehandler.core.GestureHandler class RNGestureHandlerRootView(context: Context?) : ReactViewGroup(context) { private var moduleId: Int = -1 @@ -39,6 +40,10 @@ class RNGestureHandlerRootView(context: Context?) : ReactViewGroup(context) { rootHelper?.tearDown() } + fun recordHandlerIfNotPresent(handler: GestureHandler) { + rootHelper?.recordHandlerIfNotPresent(handler) + } + override fun dispatchTouchEvent(event: MotionEvent) = if (rootViewEnabled && rootHelper!!.dispatchTouchEvent(event)) { true } else {