[Android] Fix ScrollView invalid pointer id during navigation#4177
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes an Android crash (IllegalArgumentException: pointerIndex out of range) that occurred when multi-touch gestures on a ScrollView continued to be forwarded to the native view after its host screen had been moved to mDisappearingChildren during a native-stack navigation transition. The reachability check in GestureHandlerOrchestrator is updated to detect this "logically detached but still drawn" state.
Changes:
- Rewrites
isViewAttachedUnderWrapperto traverse from the view up viaparent.indexOfChild(current), treating a child whose parent no longer lists it (disappearing child) as detached, so the orchestrator cancels the handler instead of forwarding events that hit the brokenmActivePointerIdstate.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
m-bert
approved these changes
May 14, 2026
m-bert
left a comment
Collaborator
There was a problem hiding this comment.
Sadly it doesn't reproduce on my own device 😞 But luckily it does on emulator 😄
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #3921
The flow for this crash was:
NativeViewGestureHandlerattached.mChildrentomDisappearingChildren- it's now considered unmounted, but its lifetime is prolonged for the animation to finish. A syntheticACTION_CANCELevent is dispatched by the OS, Scrollview mounted on this screen receives the event and setsmActivePointerId = INVALID_POINTERas a result.NativeViewGestureHandlerforwards that event to the ScrollView, despite it now being "unmounted". Since its internal tracking has been reset, it tries to look for a pointer with an index ofINVALID_POINTER (-1), which throws an exception.Gesture Handler has a path that should prevent this from happening (checking
isViewAttachedUnderWrapperbefore passing an event to the handler), however, due to the exiting animation, the view remained partially mounted. Android clearsparent -> childlink, but notchild -> parent. RNGH was using the second one to ensure the view is still a valid target for events.This PR changes the behavior of
isViewAttachedUnderWrapperto rely on the first link, which is cleared. This is technically a breaking change, since now all gestures on the outgoing screen are canceled as soon as navigation starts, but I'd classify this change in behavior as a bug fix.Test plan
Run the reproduction code, tap on any of the items. During the 500ms window between tap and navigation start, begin a multi-touch gesture on the scroll view (like a pinch). Release the pointers DURING the navigation animation. Before this change, the app crashes, after this change, it does not.
Reproduction code