@@ -9,6 +9,7 @@ import android.widget.ScrollView
9
9
import com.facebook.react.views.scroll.ReactScrollView
10
10
import com.facebook.react.views.swiperefresh.ReactSwipeRefreshLayout
11
11
import com.facebook.react.views.textinput.ReactEditText
12
+ import com.facebook.react.views.view.ReactViewGroup
12
13
import com.swmansion.gesturehandler.react.RNGestureHandlerButtonViewManager
13
14
import com.swmansion.gesturehandler.react.isScreenReaderOn
14
15
@@ -79,6 +80,7 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
79
80
is ReactEditText -> this .hook = EditTextHook (this , view)
80
81
is ReactSwipeRefreshLayout -> this .hook = SwipeRefreshLayoutHook (this , view)
81
82
is ReactScrollView -> this .hook = ScrollViewHook ()
83
+ is ReactViewGroup -> this .hook = ReactViewGroupHook ()
82
84
}
83
85
}
84
86
@@ -99,7 +101,7 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
99
101
if (state == STATE_UNDETERMINED && ! hook.canBegin(event)) {
100
102
cancel()
101
103
} else {
102
- view.onTouchEvent( event)
104
+ hook.sendTouchEvent(view, event)
103
105
if ((state == STATE_UNDETERMINED || state == STATE_BEGAN ) && view.isPressed) {
104
106
activate()
105
107
}
@@ -116,12 +118,12 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
116
118
when {
117
119
shouldActivateOnStart -> {
118
120
tryIntercept(view, event)
119
- view.onTouchEvent( event)
121
+ hook.sendTouchEvent(view, event)
120
122
activate()
121
123
}
122
124
123
125
tryIntercept(view, event) -> {
124
- view.onTouchEvent( event)
126
+ hook.sendTouchEvent(view, event)
125
127
activate()
126
128
}
127
129
@@ -136,7 +138,7 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
136
138
}
137
139
}
138
140
} else if (state == STATE_ACTIVE ) {
139
- view.onTouchEvent( event)
141
+ hook.sendTouchEvent(view, event)
140
142
}
141
143
}
142
144
@@ -145,7 +147,7 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
145
147
val event = MotionEvent .obtain(time, time, MotionEvent .ACTION_CANCEL , 0f , 0f , 0 ).apply {
146
148
action = MotionEvent .ACTION_CANCEL
147
149
}
148
- view !! .onTouchEvent( event)
150
+ hook.sendTouchEvent(view, event)
149
151
event.recycle()
150
152
}
151
153
@@ -199,6 +201,11 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
199
201
* by this one.
200
202
*/
201
203
fun shouldCancelRootViewGestureHandlerIfNecessary () = false
204
+
205
+ /* *
206
+ * Passes the event down to the underlying view using the correct method.
207
+ */
208
+ fun sendTouchEvent (view : View ? , event : MotionEvent ) = view?.onTouchEvent(event)
202
209
}
203
210
204
211
private class EditTextHook (
@@ -278,4 +285,12 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
278
285
private class ScrollViewHook : NativeViewGestureHandlerHook {
279
286
override fun shouldCancelRootViewGestureHandlerIfNecessary () = true
280
287
}
288
+
289
+ private class ReactViewGroupHook : NativeViewGestureHandlerHook {
290
+ // There are cases where a native component is wrapped with a `ReactViewGroup` (the component is rendered
291
+ // inside a `<View />` component in JS). In such cases, calling `onTouchEvent` wouldn't work as those are
292
+ // ignored by the wrapper view. Instead `dispatchTouchEvent` can be used, which causes the view to dispatch
293
+ // the event to its children.
294
+ override fun sendTouchEvent (view : View ? , event : MotionEvent ) = view?.dispatchTouchEvent(event)
295
+ }
281
296
}
0 commit comments