wix / react-native-navigation

A complete native navigation solution for React Native
https://wix.github.io/react-native-navigation/
MIT License
13.02k stars 2.67k forks source link

[Android] Wrong user's tap area in overlay #7786

Open v-korotkov opened 11 months ago

v-korotkov commented 11 months ago

Hi!

I use: "react-native": "0.72.4", "react-native-navigation": "^7.37.0",

I faced an annoying problem with overlays on Android. I show an overlay with a not full-screen view with interceptTouchOutside: false. For example, this view is {x: 0, y: 500, width: 100, height: 100}

When the user tries to tap the overlay the app receives a tap through the overlay (under it). Also, when the user tries to tap an area {x: 0, y: 0, width: 100, height: 100} through overlay (using interceptTouchOutside: false) it is blocked for taps.

It works well on iOS. Also, it worked well on older versions of react-native and react-native-navigation.

I found a problem in react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/MotionEvent.kt

When we use the old version of the code our not full-screen overlay view performs getHitRect in the full-screen parent, so it works correctly.

view ?: return false
view.getHitRect(hitRect)
return hitRect.contains(x.toInt(), y.toInt())

However, when we started to use the new version of the code, we had an issue. It happens cause we use a child of this view from getChildAt instead of the original view for the getHitRect method.

val viewGroup = (view as? ViewGroup)?.getChildAt(0) as? ViewGroup ?: view
viewGroup?.getHitRect(hitRect)
return hitRect.contains(x.toInt(), y.toInt())

Android View getHitRect The documentation says that getHitRect - Hit rectangle in parent's coordinates.

Therefore, when we use the original view for getHitRect, it calculates the hit for his full-screen parent, but when we use a view's child, it calculates the hit for the original view as a parent.

So, when the user taps on {x: 50, y: 550} coordinates on the screen, it will be just {x:50, y:50} in the not full-screen parent, and the blocking tap area for overlay will be translated to the top of the screen in the wrong place.

Additional changes: typo in REACT_NATVE_VERSION_MINOR

I prepared changes to fix this issue. Let's review and apply ones.

lfaz commented 10 months ago

Had similiar issues on android, this fixed! EDIT: its not consistent, can't recommand as an actual fix!

v-korotkov commented 10 months ago

Had similiar issues on android, this fixed! EDIT: its not consistent, can't recommand as an actual fix!

Could you please add the specific versions of "react-native" and "react-native-navigation" where it was fixed and works fine now? I have a stable reproduction of this issue since updating to the latest versions of these modules ("react-native": "0.72.4" and "react-native-navigation": "^7.37.0"). Therefore I have to use a workaround in my code to avoid this issue in the "react-native-navigation" module.

I know that the current code has already had changes that trying to fix a similar problem on Android (problem, PR, commit), but it is obviously the wrong way to fix it because it adds a new issue to the latest versions.

If we want to resolve the old problem too we should consider updating to the latest version or suggest a more specific way to detect the case when we should use child view instead of the original view instead of just always using it by default.

jyoti-63 commented 6 months ago

Is third commit [46349889ef510a2de2d84f956b366e63aac20533](REACT_NATIVE_VERSION_MINOR typo) required in this fix ?

v-korotkov commented 5 months ago

Is third commit [4634988](REACT_NATIVE_VERSION_MINOR typo) required in this fix ?

No, this is not needed for the problem fix, it was made just as an additional typo fix.

stale[bot] commented 4 months ago

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.