react-navigation
react-navigation copied to clipboard
Pressable elements not working in native-stack on Android devices with new architecture
Current behavior
When using Android devices (iOS and Android emulator is fine) you cannot use onPress in the header bar. onPressIn and onPress out does work. This was tested mostly with Samsung devices. This only happens with native-stack / Expo Router. Please have a look here: https://github.com/expo/expo/issues/30032 Further information also in the linked issue in the facebook/react-native repo.
Expected behavior
onPress should work also on physical Android devices.
Reproduction
https://github.com/DrZoidberg09/RN-Android-Touch-Issue/
Platform
- [X] Android
- [ ] iOS
- [ ] Web
- [ ] Windows
- [ ] MacOS
Packages
- [ ] @react-navigation/bottom-tabs
- [ ] @react-navigation/drawer
- [ ] @react-navigation/material-top-tabs
- [ ] @react-navigation/stack
- [X] @react-navigation/native-stack
- [ ] react-native-tab-view
Environment
- [] I've removed the packages that I don't use
| package | version |
|---|---|
| @react-navigation/native | |
| @react-navigation/bottom-tabs | |
| @react-navigation/drawer | |
| @react-navigation/material-top-tabs | |
| @react-navigation/stack | |
| @react-navigation/native-stack | |
| react-native-safe-area-context | |
| react-native-screens | |
| react-native-gesture-handler | |
| react-native-reanimated | |
| react-native-tab-view | |
| react-native-pager-view | |
| react-native | |
| expo | |
| node | |
| npm or yarn |
Couldn't find version numbers for the following packages in the issue:
@react-navigation/native@react-navigation/bottom-tabs@react-navigation/drawer@react-navigation/material-top-tabs@react-navigation/stackreact-native-tab-view
Can you update the issue to include version numbers for those packages? The version numbers must match the format 1.2.3.
Hey! Thanks for opening the issue. Seems that this issue is related to react-native-screens library which is a dependency of React Navigation. Can you also post your issue in this repo so that it's notified to the maintainers of that library? This will help us fix the issue faster since it's upto the maintainers of that library to investigate it.
https://github.com/software-mansion/react-native-screens/issues/2219
same thing in ios https://github.com/expo/expo/issues/32927
I am having same issue. For pressable buttons I have been able to work around using onPressOut instead of onPress. I am seeking a workaround for React-Native Navigation since back buttons are unresponsive. Is anyone aware of any workarounds for this condition? It doesn't matter if new architecture is enabled or disabled. Popped up as soon as we upgraded to version 52 of the Expo Go SDK.
Hey!
I'm also experiencing he issue using Expo (new arch enabled) and React Navigation. I did the same workaround by replacing all of the onPress calls to onPressOut which solved the issue for now, but it's something to be addressed.
On iOS it works properly.
having the same issue on Android after enabling the new arch
Having same issue, but strangely I'm getting it on iOS only, android is working for me. Switching to onPressIn, onPressOut hasn't worked out for me.
Same issue,
even onPressIn and onPressOut behave weirdly when this bug happens.
onPressOut is fired immediately after onPressIn even if I don't lift off my finger.
Also the button is clickable using emulator but not on physical device, maybe it registers me moving like a pixel or so and hence fires onPressOut and not onPress?
In my case, I resolved the issue on Android by removing any additional text associated with the navigation. Allowing IOS to natively add the 'Back' prompts solved my issue.
From: Kartikey Chauhan @.> Sent: Tuesday, February 4, 2025 5:47 AM To: react-navigation/react-navigation @.> Cc: Mike Eldredge @.>; Comment @.> Subject: Re: [react-navigation/react-navigation] Pressable elements not working in native-stack on Android devices with new architecture (Issue #12039)
Same issue, even onPressIn and onPressOut behave weirdly when this bug happens. onPressOut is fired immediately after onPressIn even if I don't lift off my finger.
Also the button is clickable using emulator but not on physical device, maybe it registers me moving like a pixel or so and hence fires onPressOut and not onPress?
— Reply to this email directly, view it on GitHubhttps://github.com/react-navigation/react-navigation/issues/12039#issuecomment-2633532879, or unsubscribehttps://github.com/notifications/unsubscribe-auth/BAUEXBGVJVQE5EC35RR676T2OCLDLAVCNFSM6AAAAABKBZQIA2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMMZTGUZTEOBXHE. You are receiving this because you commented.Message ID: @.***>
I had the same issue and I solved it changing it to onPressOut (or onPressIn), everything else that is not in the header works fine for me with onPress,
I also tried handling it for a while with onPressOut, but the workaround is not good enough.
Let's say I want to press an action, but just when I touched the screen I change my mind and drag my finger away so that the press does not execute. With onPressOut and onPressIn it does, unfortunately.
My use case is a custom button built with Pressable.
Last time when I tried to do something about it I stored the boundaries for the button to its state and check them against coordinates from the onPress events. I tried to get them with onLayout, but x and y are both 0 (width and height dimensions were ok), so I couldn't use this approach.
My next attempt was with measureInWindow. This was interesting: y was -543, so that's outside the screen even if the button appears on the screen. Comparing it to coordinates from press events within the screen fails, of course. This only happens when the Pressable is in a navigatoin header. Works in other cases, so my next try was with a huge pressRetentionOffset to compensate for the big negative y. This thing worked:
pressRetentionOffset={{ top: 600, bottom: 700, left: 0, right: 0 }}
Of course I wouldn't go with such a junk hardcoded workaround. I'm waiting for a version that actually fixes the cause and I'll get back to onPressOut until then.
I'm writing this to point out that onLayout fails to get the correct position and its result differs from the useLayoutEffect and measureInWindow approach. The latter probably gets the technically correct value if the retention offset confirmed it, but that's not where the component is displayed. Maybe this information will be helpful in debugging and fixing the issue.
Having the same issue with onPress on elements in navigation header on android. expo 52.0.35 and @react-navigation/native-stack 7.2.0 My solution is to use react-native-gesture-handler:
import Icon from "@expo/vector-icons/MaterialCommunityIcons";
import { ComponentProps } from "react";
import { Platform } from "react-native";
import { TouchableOpacity } from "react-native-gesture-handler";
export const HeaderIcon = (
props: Omit<ComponentProps<typeof Icon>, "onPress"> & {
onPress: ComponentProps<typeof TouchableOpacity>["onPress"];
},
) => {
const { onPress, ...restProps } = props;
return Platform.OS === "android" ? (
<TouchableOpacity onPress={onPress}>
<Icon {...restProps} />
</TouchableOpacity>
) : (
<Icon {...props} />
);
};
I also have issues with text inputs. They are not focusable. Can be reproduced on Samsung real devices using Tamagui Sheet with Text Inputs and Buttons inside it: https://github.com/tamagui/tamagui/issues/3288
Disabling new architecture fixes the issue.
EDIT:
I can confirm @Chugunenok suggestion works good for me (importing both <TextInput />and <Button /> from gesture-handler and use them inside Tamagui <Sheet />).
Buttons don't work very well in <Modal /> imported from react-native though. Didn't test <TextInput /> inside <Modal />.
Hi any update on this ?
Shout out to @LunatiqueCoder and @Chugunenok. Leveraging Pressable along with onPressOut did it for me.
Shout out to @LunatiqueCoder and @Chugunenok. Leveraging
Pressablealong withonPressOutdid it for me.
onPressOut is only a workaround that may result in unexpected behavior for most users:
When I press a button and immediately change my mind just before I finish the press, I drag my finger away from the button and release it elsewhere. It's a common way for users to cancel a button press. Setting the callback action to onPressOut or onPressIn will not allow users to do that.
You could go the old fashion way with a dialogue:
- Are you sure that you want to press this button? 😜
Also having this issue with onPress on elements in navigation header on android. For now working around it with onPressOut, but would like a fix to this!
Have the same issue using Tamagui Select component.
setting newArchEnabled to false fix the problem, but I don't really wanna do that, and can't really do much since its Tamagui's code, did anyone found another fix for that? please mention me 🙏🏻
Have the same issue as well. Some phones can use onPress, some phones not. I encountered this issue at phones it's using Samsung OneUI
Related to https://github.com/revcel/revcel/pull/1 use { TouchableOpacity } from "react-native-gesture-handler";
Having the same issue also, isn't there an official solution for this issue out yet?
Im looking for a solution still. I'm agree with PressOut and PressIn is not a finally solution for this issue. Does Anyone know if there is a final solution for this?
Im looking for a solution still. I'm agree with PressOut and PressIn is not a finally solution for this issue. Does Anyone know if there is a final solution for this?
best i found so far is using Pressable from react-native-gesture-handler main issue is that it doesn't work exactly like all the other Pressable. Like it doesn't support some style (border, ...) and in my case i just can't use it with tamagui styled (throw error).
So it's unpractical custom code pretty much but seems to avoid the issue on android at least.
+1