Skip to content

[Android] Fix onTouches* callbacks being called for all gestures#3596

Merged
m-bert merged 5 commits intomainfrom
@mbert/fix-touch-events-android
Jul 4, 2025
Merged

[Android] Fix onTouches* callbacks being called for all gestures#3596
m-bert merged 5 commits intomainfrom
@mbert/fix-touch-events-android

Conversation

@m-bert
Copy link
Contributor

@m-bert m-bert commented Jul 4, 2025

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

Tested on the following example:
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',
  },
});

@m-bert m-bert marked this pull request as ready for review July 4, 2025 07:42
@m-bert m-bert requested review from MatiPl01, j-piasecki and latekvo July 4, 2025 07:43
Copy link
Member

@MatiPl01 MatiPl01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works like a charm! I patched gesture handler in my lib and the issue is gone. Thanks for addressing the issue.

@m-bert m-bert merged commit f176465 into main Jul 4, 2025
4 checks passed
@m-bert m-bert deleted the @mbert/fix-touch-events-android branch July 4, 2025 10:16
j-piasecki pushed a commit that referenced this pull request Jul 7, 2025
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Touches up/down callbacks fired on multiple gesture detectors when should fire for only one

4 participants