Skip to content

fix(android): Finish ScrollView drags on ACTION_CANCEL - #59286

Open
ddx533534 wants to merge 3 commits into
react:mainfrom
ddx533534:fix/android-scrollview-cancel-drag
Open

ddx533534 wants to merge 3 commits into
react:mainfrom
ddx533534:fix/android-scrollview-cancel-drag

Conversation

@ddx533534

@ddx533534 ddx533534 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

When a parent intercepts an already-started ScrollView drag, Android delivers ACTION_CANCEL. The current ACTION_UP-only condition skips END_DRAG, the native gesture end notification, resetting dragging, and post-touch cleanup.

Handle ACTION_CANCEL alongside ACTION_UP in ReactScrollView, ReactHorizontalScrollView, and ReactNestedScrollView. Cancellation preserves the tracked velocity and uses the existing post-touch settling pipeline, including configured momentum events and page alignment. The nested component was regenerated with its source generator.

Changelog:

[ANDROID] [FIXED] - Finish interrupted ScrollView drags when receiving ACTION_CANCEL.

Test Plan:

Current upstream source: 12 Robolectric cases passed, 0 failures and 0 skipped, on c7429b0 plus this patch. Each vertical, horizontal, and nested component is covered for cancellation ending a drag exactly once, cancellation without dragging, normal UP behavior, and post-touch cleanup notifying native scroll-ended listeners and disabling the FPS listener.

./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests com.facebook.react.views.scroll.ReactScrollViewTouchCancelTest -PreactNativeArchitectures=arm64-v8a -PndkVersion=29.0.13113456 -Preact.internal.useHermesStable=true -x :packages:react-native:ReactAndroid:prepareNative3pDependencies -x :packages:react-native:ReactAndroid:preparePrefab

The JVM run compiled RN Kotlin/Java from source; the excluded tasks prepare C++ headers. git diff --check, formatting of the new Kotlin test, and the nested-scroll generator --verify check also passed.

Android emulator: Built before/after native harness APKs using the real RN 0.83.10 vertical ReactScrollView on Android 16 ARM64. The RN source differs only in the terminal-action condition. After RN emits BEGIN_DRAG, the parent intercepts the stream and Android itself delivers CANCEL.

After parent interception Before After
BEGIN_DRAG / END_DRAG 1 / 0 1 / 1
Native gesture started / ended 1 / 0 1 / 1
dragging true false
FPS listener after settling enabled disabled
Momentum begin / end (enabled) 0 / 0 1 / 1

All 12 before/after emulator scenarios matched expectations: drag + cancel, drag + up, cancel without dragging, repeated cancellation, paging-enabled cancellation, and cancellation with momentum events disabled. Paging-enabled cancellation settled with balanced momentum events.

The recordings demonstrate native event emission and cleanup on RN 0.83.10; the harness does not run a JS VM. Current-source coverage for horizontal/nested components comes from the Robolectric tests above.

Reproduction evidence

Before the fix: END_DRAG=0, dragging=true, FPS listener remains enabled after cancellation.

before.mp4

After the fix: END_DRAG=1, dragging=false, native gesture end and post-touch cleanup complete.

after.mp4

Download the standalone native reproducer, recordings, and emulator results. See its README for setup and the exact verification scope.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 21, 2026
@ddx533534

Copy link
Copy Markdown
Contributor Author

Reproduction recordings and standalone native harness:

before.mp4
after.mp4

rn-scroll-cancel-reproducer.zip

@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 21, 2026
@meta-codesync

meta-codesync Bot commented Oct 21, 2026

Copy link
Copy Markdown

@javache has imported this pull request. If you are a Meta employee, you can view this in D126637111.

This branch has not been deployed

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants