Skip to content

Commit 30401e7

Browse files
m-bertj-piasecki
authored andcommitted
[Android] Fix onTouches* callbacks being called for all gestures (#3596)
## Description Logic behind sending touch events on `android` dispatches events into all gesture handlers registered in the orchestrator. This means that interaction with one `GestureDetector` triggers callbacks on the others. This PR adds check for tracked pointer, so that handlers respond only to those that they are tracking. Fixes #3543 ## Test plan <details> <summary>Tested on the following example:</summary> ```jsx import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { Gesture, GestureDetector, GestureHandlerRootView, } from 'react-native-gesture-handler'; type BoxProps = { label: string; }; function Box({ label }: BoxProps) { const manual = Gesture.Manual() .onTouchesDown((e) => { console.log('down', label, e.handlerTag); }) .onTouchesUp((e) => { console.log('up', label, e.handlerTag); }) .onTouchesCancelled(() => { console.log('cancelled', label); }); return ( <GestureDetector gesture={manual}> <View style={styles.box}> <Text style={styles.text}>{label}</Text> </View> </GestureDetector> ); } export default function EmptyExample() { return ( <GestureHandlerRootView style={styles.container}> <Box label="1" /> <Box label="2" /> </GestureHandlerRootView> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 10, }, box: { width: 100, height: 100, backgroundColor: 'red', alignItems: 'center', justifyContent: 'center', }, text: { color: 'white', fontSize: 20, fontWeight: 'bold', }, }); ``` </details>
1 parent 1df5419 commit 30401e7

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,19 +203,25 @@ open class GestureHandler {
203203
}
204204

205205
fun startTrackingPointer(pointerId: Int) {
206-
if (trackedPointerIDs[pointerId] == -1) {
207-
trackedPointerIDs[pointerId] = findNextLocalPointerId()
208-
trackedPointersIDsCount++
206+
if (isTrackingPointer(pointerId)) {
207+
return
209208
}
209+
210+
trackedPointerIDs[pointerId] = findNextLocalPointerId()
211+
trackedPointersIDsCount++
210212
}
211213

212214
fun stopTrackingPointer(pointerId: Int) {
213-
if (trackedPointerIDs[pointerId] != -1) {
214-
trackedPointerIDs[pointerId] = -1
215-
trackedPointersIDsCount--
215+
if (!isTrackingPointer(pointerId)) {
216+
return
216217
}
218+
219+
trackedPointerIDs[pointerId] = -1
220+
trackedPointersIDsCount--
217221
}
218222

223+
private fun isTrackingPointer(pointerId: Int) = trackedPointerIDs[pointerId] != -1
224+
219225
private fun needAdapt(event: MotionEvent): Boolean {
220226
if (event.pointerCount != trackedPointersIDsCount) {
221227
return true
@@ -573,11 +579,11 @@ open class GestureHandler {
573579
onStateChange(newState, oldState)
574580
}
575581

576-
fun wantEvents(): Boolean = isEnabled &&
582+
fun wantsEvent(event: MotionEvent): Boolean = isEnabled &&
577583
state != STATE_FAILED &&
578584
state != STATE_CANCELLED &&
579585
state != STATE_END &&
580-
trackedPointersIDsCount > 0
586+
isTrackingPointer(event.getPointerId(event.actionIndex))
581587

582588
open fun shouldRequireToWaitForFailure(handler: GestureHandler): Boolean {
583589
if (handler === this) {

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ class GestureHandlerOrchestrator(
249249
// on Arrays.sort providing a stable sort (as children are registered in order in which they
250250
// should be tested)
251251
preparedHandlers.sortWith(handlersComparator)
252+
252253
for (handler in preparedHandlers) {
253254
deliverEventToGestureHandler(handler, event)
254255
}
@@ -273,7 +274,8 @@ class GestureHandlerOrchestrator(
273274
handler.cancel()
274275
return
275276
}
276-
if (!handler.wantEvents()) {
277+
278+
if (!handler.wantsEvent(sourceEvent)) {
277279
return
278280
}
279281

0 commit comments

Comments
 (0)