[Android] onMarkerClick reports the marker's coordinate as the press position instead of the touch point (tapLocation is already captured)
Summary
On Android, a marker press reports the marker's coordinate as the event's coordinate/position, not the point the user actually touched. MapView.onMarkerClick calls makeClickEventData(marker.getPosition()). The touch point is already captured in dispatchTouchEvent as tapLocation, and the polygon and polyline click handlers already use it; markers are the odd one out.
This matters because Google Maps' hit region for custom image markers is offset and oversized (measured on a Samsung A13: a finger dead-centre on pin b is reported as the pin beside it, and a tap on empty map ~30dp above a pin counts as that pin). An app that wants to resolve the tap itself against the drawn pin shapes needs the finger position, and today the payload throws it away.
Reproducible sample code
<Marker
coordinate={{ latitude: -41.29, longitude: 174.78 }}
image={require('./pin.png')}
onPress={(e) => console.log(e.nativeEvent.coordinate, e.nativeEvent.position)}
/>Steps to reproduce
Tap the marker off-centre (e.g. its top-right corner).
Expected result
coordinate/position describe the touched point, as they do for MapView.onPress, polygons and polylines.
Actual result
They are exactly the marker's own coordinate, whatever was touched.
Fix
--- a/android/src/main/java/com/rnmaps/maps/MapView.java
+++ b/android/src/main/java/com/rnmaps/maps/MapView.java
@@ -572,12 +572,14 @@
public boolean onMarkerClick(@NonNull Marker marker) {
MapMarker airMapMarker = getMarkerMap(marker);
- WritableMap eventData = makeClickEventData(marker.getPosition());
+ // Report the touched point (already captured in dispatchTouchEvent),
+ // as polygon/polyline presses do.
+ LatLng pressLoc = tapLocation != null ? tapLocation : marker.getPosition();
+ WritableMap eventData = makeClickEventData(pressLoc);
eventData.putString("action", "marker-press");
eventData.putString("id", airMapMarker.getIdentifier());
airMapMarker.dispatchEvent(eventData, OnPressEvent::new);
- WritableMap mapEventData = makeClickEventData(marker.getPosition());
+ WritableMap mapEventData = makeClickEventData(pressLoc);
mapEventData.putString("action", "marker-press");
mapEventData.putString("id", airMapMarker.getIdentifier());If keeping the marker's coordinate in coordinate is preferred for compatibility, an additional field carrying the touch point would serve the same purpose.
React Native Maps Version
1.29.0 (present on master, v1.29.2)
What platforms are you seeing the problem on?
Android
React Native Version
0.86 (Expo SDK 57), New Architecture
Device(s)
Samsung A13, Pixel 9 Pro, arm64 emulator (API 36)
Additional information
Verified with an instrumented test on the app's own ReactHost that injects real pointer events and reads the JS payload back. A full write-up will be at https://zackdesign.biz/which-pin-did-you-tap/ shortly.
Source: react-native-maps/react-native-maps