diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerView.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerView.kt index e4fa86b33..294fd112c 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerView.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerView.kt @@ -11,6 +11,7 @@ import com.mapbox.geojson.Point import com.mapbox.maps.ViewAnnotationAnchor import com.mapbox.maps.ViewAnnotationOptions import com.mapbox.maps.viewannotation.viewAnnotationOptions +import com.facebook.react.uimanager.PointerEvents import com.rnmapbox.rnmbx.components.AbstractMapFeature import com.rnmapbox.rnmbx.components.RemovalReason import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView @@ -33,6 +34,7 @@ class RNMBXMarkerView(context: Context?, private val mManager: RNMBXMarkerViewMa private var mAllowOverlap = false private var mAllowOverlapWithPuck = false private var mIsSelected = false + private var mPointerEvents: PointerEvents = PointerEvents.AUTO fun setCoordinate(point: Point?) { mCoordinate = point @@ -63,8 +65,14 @@ class RNMBXMarkerView(context: Context?, private val mManager: RNMBXMarkerViewMa // region View methods + fun setContentPointerEvents(pointerEvents: PointerEvents) { + mPointerEvents = pointerEvents + (mView as? RNMBXMarkerViewContent)?.setExternalPointerEvents(pointerEvents) + } + override fun addView(childView: View, childPosition: Int) { mView = childView + (childView as? RNMBXMarkerViewContent)?.setExternalPointerEvents(mPointerEvents) // Note: Do not call this method on `super`. The view is added manually. } diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt index 561eed102..29a9ad3b6 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt @@ -6,12 +6,18 @@ import android.view.View.MeasureSpec import android.view.ViewGroup import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.ReactContext +import com.facebook.react.uimanager.PointerEvents import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.views.view.ReactViewGroup import com.rnmapbox.rnmbx.components.camera.BaseEvent class RNMBXMarkerViewContent(context: Context): ReactViewGroup(context) { var inAdd: Boolean = false + private var externalPointerEvents: PointerEvents = PointerEvents.AUTO + + fun setExternalPointerEvents(pointerEvents: PointerEvents) { + externalPointerEvents = pointerEvents + } // Track last reported translation to avoid feedback loop: // Mapbox sets setTranslationX(512) → we fire event → JS sets transform:[{translateX:512}] @@ -29,6 +35,9 @@ class RNMBXMarkerViewContent(context: Context): ReactViewGroup(context) { } override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + if (externalPointerEvents == PointerEvents.NONE) { + return false + } // On ACTION_DOWN, tell the parent MapView not to intercept subsequent MOVE/UP // events for pan/zoom recognition — that would send CANCEL to child Pressables // and suppress onPress. Android resets the disallow flag on each new DOWN, so diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt index 55dc04cdd..c54c7af41 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt @@ -8,8 +8,11 @@ import com.facebook.react.bridge.ReactApplicationContext import com.rnmapbox.rnmbx.components.AbstractEventEmitter import com.facebook.react.uimanager.annotations.ReactProp import com.facebook.react.common.MapBuilder +import com.facebook.react.uimanager.PointerEvents +import com.facebook.react.uimanager.ReactStylesDiffMap import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewManagerDelegate +import com.facebook.react.uimanager.ViewProps import com.facebook.react.viewmanagers.RNMBXMarkerViewManagerDelegate import com.facebook.react.viewmanagers.RNMBXMarkerViewManagerInterface import com.mapbox.maps.ScreenCoordinate @@ -72,6 +75,17 @@ class RNMBXMarkerViewManager(reactApplicationContext: ReactApplicationContext) : markerView.setIsSelected(isSelected.asBoolean()) } + override fun updateProperties(viewToUpdate: RNMBXMarkerView, props: ReactStylesDiffMap) { + super.updateProperties(viewToUpdate, props) + // The codegen delegate does not forward the standard `pointerEvents` ViewProp — it falls + // to BaseViewManagerDelegate which ignores it. Intercept it here so the marker content + // view (which lives in a separate Mapbox view hierarchy) can honour it. + if (props.hasKey(ViewProps.POINTER_EVENTS)) { + val pe = PointerEvents.parsePointerEvents(props.getString(ViewProps.POINTER_EVENTS)) + viewToUpdate.setContentPointerEvents(pe) + } + } + override fun createViewInstance(reactContext: ThemedReactContext): RNMBXMarkerView { return RNMBXMarkerView(reactContext, this) } diff --git a/example/src/examples/Annotations/MarkerView.tsx b/example/src/examples/Annotations/MarkerView.tsx index 1ea6380b1..3ac99b6a2 100644 --- a/example/src/examples/Annotations/MarkerView.tsx +++ b/example/src/examples/Annotations/MarkerView.tsx @@ -274,12 +274,20 @@ const ShowMarkerView = () => { React.useState(INITIAL_COORDINATES); const [allowOverlapWithPuck, setAllowOverlapWithPuck] = React.useState(false); + const [pointerEventsNone, setPointerEventsNone] = + React.useState(false); + + const [mapMoveCount, setMapMoveCount] = React.useState(0); const onPressMap = (e: GeoJSON.Feature) => { const geometry = e.geometry as GeoJSON.Point; setPointList((pl) => [...pl, geometry.coordinates]); }; + const onRegionDidChange = React.useCallback(() => { + setMapMoveCount((c) => c + 1); + }, []); + return ( <>