Commit 757265d
authored
Fix grabbing delegate in
## Description
On android unction `setPressed` grabs the delagate without any checks.
As a result, in specific cases - such as in #3735 - pressed is
registered when it should not be.
## Test plan
The same as in #3735, tested on the following code.
<details>
```
import { useEffect, useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import {
GestureHandlerRootView,
Pressable,
} from "react-native-gesture-handler";
import {
KeyboardProvider,
KeyboardStickyView,
} from "react-native-keyboard-controller";
import {
SafeAreaProvider,
useSafeAreaInsets,
} from "react-native-safe-area-context";
const rippleConfig = {
color: "#666666",
borderless: true,
foreground: true,
};
function App() {
return (
<SafeAreaProvider>
<GestureHandlerRootView>
<KeyboardProvider
statusBarTranslucent={true}
navigationBarTranslucent={true}
preserveEdgeToEdge={true}
>
<AppContent />
</KeyboardProvider>
</GestureHandlerRootView>
</SafeAreaProvider>
);
}
function Snackbar({
visible,
setSnackbarVisible,
}: {
visible?: boolean;
setSnackbarVisible: (visible: boolean) => void;
}) {
const safeAreaInsets = useSafeAreaInsets();
useEffect(() => {
const timeout = setTimeout(() => {
setSnackbarVisible(false);
}, 3000);
return () => clearTimeout(timeout);
}, [visible, setSnackbarVisible]);
return (
<KeyboardStickyView offset={{ closed: -safeAreaInsets.bottom, opened: 0 }}>
{visible && (
<View style={[styles.snackbar]}>
<Text style={styles.snackbarText}>Snackbar</Text>
</View>
)}
</KeyboardStickyView>
);
}
function Screen({
setSnackbarVisible,
}: {
setSnackbarVisible: (visible: boolean) => void;
}) {
const safeAreaInsets = useSafeAreaInsets();
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount(count + 1);
};
const handleButtonPress = () => {
setSnackbarVisible(true);
};
return (
<View
style={[
styles.container,
{
flex: 1,
paddingTop: safeAreaInsets.top,
paddingBottom: safeAreaInsets.bottom,
},
]}
>
<View style={styles.centerContent}>
<Text style={styles.countText}>Count: {count}</Text>
<Pressable
style={styles.button}
onPress={incrementCount}
android_ripple={rippleConfig}
>
<Text style={styles.buttonText}>Increment</Text>
</Pressable>
</View>
<View style={styles.bottomContent}>
<Pressable
style={styles.button}
onPress={handleButtonPress}
android_ripple={rippleConfig}
>
<Text style={styles.buttonText}>Show snackbar</Text>
</Pressable>
</View>
</View>
);
}
function AppContent() {
const [snackbarVisible, setSnackbarVisible] = useState(false);
return (
<>
<Screen setSnackbarVisible={setSnackbarVisible} />
<Snackbar
visible={snackbarVisible}
setSnackbarVisible={setSnackbarVisible}
/>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f5f5f5",
},
centerContent: {
flex: 1,
justifyContent: "center",
alignItems: "center",
paddingHorizontal: 20,
},
bottomContent: {
paddingHorizontal: 20,
paddingBottom: 20,
flexDirection: "row",
justifyContent: "center",
},
countText: {
fontSize: 24,
fontWeight: "bold",
marginBottom: 20,
color: "#333",
},
button: {
backgroundColor: "#007AFF",
paddingHorizontal: 30,
paddingVertical: 15,
borderRadius: 8,
alignItems: "center",
justifyContent: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
buttonText: {
color: "white",
fontSize: 20,
fontWeight: "600",
},
disabledButton: {
backgroundColor: "#CCCCCC",
shadowOpacity: 0.1,
elevation: 2,
},
disabledButtonText: {
color: "#666666",
},
snackbar: {
position: "absolute",
left: 15,
right: 15,
bottom: 30,
height: 50,
backgroundColor: "#008000",
paddingHorizontal: 15,
paddingVertical: 12,
borderRadius: 8,
alignItems: "center",
justifyContent: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 8,
},
snackbarText: {
color: "white",
fontSize: 14,
},
});
export default App;
```
</details>
* install `react-native-keyboard-controller`
* Press on "Increment" to see that the button/pressable works.
* Press on "Show snackbar" to show the snackbar.
* While the snackbar is visible, press the "Show snackbar" button again.
* When the snackbar is gone, observe that the ripple effect on the "Show
snackbar" button is still visible. Don't touch this button.
* Press on "Increment" and observe that it's not working anymore.setPressed (#3742)1 parent ae25b49 commit 757265d
File tree
1 file changed
+5
-10
lines changed- packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react
1 file changed
+5
-10
lines changedLines changed: 5 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
440 | 440 | | |
441 | 441 | | |
442 | 442 | | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
443 | 446 | | |
| 447 | + | |
444 | 448 | | |
445 | 449 | | |
446 | 450 | | |
| |||
515 | 519 | | |
516 | 520 | | |
517 | 521 | | |
518 | | - | |
519 | | - | |
520 | | - | |
521 | | - | |
522 | | - | |
523 | | - | |
524 | | - | |
525 | | - | |
526 | | - | |
527 | | - | |
528 | 522 | | |
529 | 523 | | |
530 | 524 | | |
| |||
535 | 529 | | |
536 | 530 | | |
537 | 531 | | |
| 532 | + | |
538 | 533 | | |
539 | 534 | | |
540 | 535 | | |
| |||
0 commit comments