Commit cbd97db
authored
[android] fixed experimental pointers breaking after pan (#3801)
## Description
In a project using experimental pointer events, activation of the pan
gesture stopped recognition of Js pointer events. This PR should resolve
this issue.
## Fix
I believe the error is due to the fact that `onCancel` calls
rootView.onChildStartedNativeGesture, which sets the
`UNSET_CHILD_VIEW_ID` in JSPointerDispatcher.kt to current view tag,
which is never cleared. This blocks pointer events from being called, as
the pointer dispatcher thinks that some child is handling a native
gesture. I added cleanup when all fingers have been lifted.
## Test plan
Enable experimental pointer events:
https://reactnative.dev/blog/2022/12/13/pointer-events-in-react-native#enable-feature-flags.
Use the following code to test the component:
<details>
```ts
import React from 'react';
import { Text, Pressable, StyleSheet } from 'react-native';
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
const END_POSITION = 200;
function App(): React.JSX.Element {
const [count, setCount] = React.useState(0);
const [pressCount, setPressCount] = React.useState(0);
const onLeft = useSharedValue(true);
const position = useSharedValue(0);
const panGesture = Gesture.Pan()
.onUpdate((e) => {
if (onLeft.value) {
position.value = e.translationX;
} else {
position.value = END_POSITION + e.translationX;
}
})
.onEnd((e) => {
if (position.value > END_POSITION / 2) {
position.value = withTiming(END_POSITION, { duration: 100 });
onLeft.value = false;
} else {
position.value = withTiming(0, { duration: 100 });
onLeft.value = true;
}
});
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: position.value }],
}));
return (
<GestureHandlerRootView style={styles.container}>
<Pressable
style={{ padding: 16, backgroundColor: '#aa0044' }}
onPointerDown={() => setCount(n => n + 1)}
onPressIn={() => setPressCount(n => n + 1)}
>
<Text style={{ color: 'black' }}>Press me</Text>
</Pressable>
<Text style={{ marginBottom: 16, color: 'black' }}>
pointer: {count} -- press: {pressCount}
</Text>
<GestureDetector gesture={panGesture}>
<Animated.View style={[styles.box, animatedStyle]} />
</GestureDetector>
</GestureHandlerRootView>
);
}
const styles = StyleSheet.create({
container: {
padding: 64,
flex: 1,
},
box: {
height: 120,
width: 120,
backgroundColor: '#b58df1',
borderRadius: 20,
marginBottom: 30,
},
});
export default App;
```
</details>
If you have experimental pointer events turned on clicking on the upper
pressable should increase both counters even after using pan gesture on
the box below. Before this PR, after panning, only one counter worked.1 parent b53b8ef commit cbd97db
File tree
2 files changed
+11
-0
lines changed- packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler
- core
- react
2 files changed
+11
-0
lines changedLines changed: 10 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
56 | 58 | | |
57 | 59 | | |
58 | 60 | | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
59 | 69 | | |
60 | 70 | | |
61 | 71 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| |||
0 commit comments