Skip to content

Comments

fix(android): Parent view steals map pan gesture#100

Open
ottor-o wants to merge 1 commit intopinpong:devfrom
ottor-o:dev
Open

fix(android): Parent view steals map pan gesture#100
ottor-o wants to merge 1 commit intopinpong:devfrom
ottor-o:dev

Conversation

@ottor-o
Copy link

@ottor-o ottor-o commented Feb 1, 2026

Pull request

Please ensure this PR targets the dev branch and follows the project conventions.
CI already runs linting, formatting, and build checks automatically.


Before submitting

  • This PR targets the dev branch (not main)
  • Commit messages follow the semantic-release format
  • No debug logs or sensitive data included

Summary

This fixes an issue where parent PagerView (and ScrollView?) steals MapView's pan gesture.


Type of change

  • Feature
  • Fix
  • Refactor
  • Internal / CI
  • Documentation

Scope

  • Android
  • iOS
  • JS
  • Example App
  • Docs

Related

List any related issues, pull requests, or discussions.
Use the format:
Fixes #123, Refs #456, Close #789


Additional notes

If you have a map inside a PagerView (and ScrollView?) with touch events enabled, they override MapView's pan gesture. The expected behaviour is to be able to pan the map normally. This is the current behaviour on iOS.

@pinpong
Copy link
Owner

pinpong commented Feb 2, 2026

Thanks for the PR,
that approach only handles down/up and doesn’t account for multi-touch or re-interception during move, which makes pinch/rotate unreliable in nested scroll containers.
This patch handles interception based on pointer count and keeps gestures stable, matching the expected iOS behavior on Android. We should also keep an eye on possible side effects of touch interception changes in complex layouts.

diff --git a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt
index 25339a8..b9953ff 100644
--- a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt
+++ b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt
@@ -10,6 +10,7 @@ import android.content.res.Configuration
 import android.graphics.Bitmap
 import android.location.Location
 import android.util.Size
+import android.view.MotionEvent
 import android.view.View
 import android.widget.FrameLayout
 import androidx.lifecycle.Lifecycle
@@ -106,6 +107,7 @@ class GoogleMapsViewImpl(
   private val urlTileOverlaysById = mutableMapOf<String, TileOverlay>()
 
   private var cameraMoveReason = -1
+  private var parentTouchInterceptDisallowed = false
 
   val componentCallbacks =
     object : ComponentCallbacks2 {
@@ -181,6 +183,52 @@ class GoogleMapsViewImpl(
         }
     }
 
+  private fun setParentTouchInterceptDisallowed(blocked: Boolean) {
+    if (parentTouchInterceptDisallowed == blocked) return
+    parentTouchInterceptDisallowed = blocked
+    var p = parent
+    while (p != null) {
+      p.requestDisallowInterceptTouchEvent(blocked)
+      p = p.parent
+    }
+  }
+
+  override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
+    val panEnabled = uiSettings?.scrollEnabled == true
+    val zoomEnabled = uiSettings?.zoomGesturesEnabled == true
+    val rotateEnabled = uiSettings?.rotateEnabled == true
+    val tiltEnabled = uiSettings?.tiltEnabled == true
+
+    val multiTouchEnabled = zoomEnabled || rotateEnabled || tiltEnabled
+    val anyMapGestureEnabled = panEnabled || multiTouchEnabled
+    if (!anyMapGestureEnabled) return super.dispatchTouchEvent(ev)
+
+    when (ev.actionMasked) {
+      MotionEvent.ACTION_DOWN,
+      MotionEvent.ACTION_MOVE,
+      MotionEvent.ACTION_POINTER_DOWN,
+      -> {
+        val pointers = ev.pointerCount
+        val shouldBlockParent = pointers >= (if (panEnabled) 1 else 2)
+        setParentTouchInterceptDisallowed(shouldBlockParent)
+      }
+
+      MotionEvent.ACTION_POINTER_UP -> {
+        val pointers = ev.pointerCount - 1
+        val shouldBlockParent = pointers >= (if (panEnabled) 1 else 2)
+        setParentTouchInterceptDisallowed(shouldBlockParent)
+      }
+
+      MotionEvent.ACTION_UP,
+      MotionEvent.ACTION_CANCEL,
+      -> {
+        setParentTouchInterceptDisallowed(false)
+      }
+    }
+
+    return super.dispatchTouchEvent(ev)
+  }
+
   override fun onCameraMoveStarted(reason: Int) =
     onUi {
       if (!mapViewLoaded) return@onUi
@@ -875,6 +923,7 @@ class GoogleMapsViewImpl(
   }
 
   override fun onDetachedFromWindow() {
+    setParentTouchInterceptDisallowed(false)
     lifecycleObserver?.let { lifecycle?.removeObserver(it) }
     lifecycle = null
     super.onDetachedFromWindow()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants