-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Android] Fix onMomentumScrollEnd similar to iOS #45187
Conversation
@cipolleschi would also love to know your thoughts as well. |
Base commit: e6dd44d |
Android is not really my area of expertise, so @javache and @cortinico would be better reviewers. A couple of points though:
|
Yup basically this. |
This looks like an issue with both New Architecture and Old (bridgeless mode is enabled from screen captures). I'm happy to work with you @Biki-das to import and land these changes since this is a gap in platforms we'd like to close |
@Abbondanzo happy to coordinate to land this, let me know how can i help 😃 |
Awesome! Would you be able to rebase and convert your changes to Kotlin? Both |
Cool,i would try to do the same tomorrow, its been a long time of the code, need to check it back and forth, thanks for your help, seeking to land this. |
109a3b5
to
0e382c3
Compare
@Abbondanzo ? were the files you mentioned converted to Kotlin, as i rebased it to the latest main,? am i doing something wrong? |
Ah, nope, my mistake! It hasn't been converted to Kotlin yet. Saw someone else working on a Kotlin conversion but that hasn't merged yet, so no need to wait |
@Abbondanzo has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
i see an internal linter fail action, obviously only meta employees are allowed to seek that, @Abbondanzo could you check and confirm the same. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i see an internal linter fail action, obviously only meta employees are allowed to seek that, @Abbondanzo could you check and confirm the same.
Yep, that's an easy fix on our end. I pulled this in and gave it a test. I've got a few change requests first but otherwise this is looking stellar!
@@ -926,6 +927,7 @@ private void handlePostTouchScrolling(int velocityX, int velocityY) { | |||
} | |||
|
|||
if (mSendMomentumEvents) { | |||
enableFpsListener(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could these tweaks to the FPS listener be removed? Event dispatching for touch events shouldn't be changing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall i just remove them as far as i can remember they are for per monitoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would restore the original behavior here, removing modifications of the enable/disableFpsListener methods from this method
} else { | ||
scrollView.scrollTo(data.mDestX, data.mDestY); | ||
ReactScrollViewHelper.emitScrollMomentumEndEvent(scrollView); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While iOS does this for non-animated views, this is a bug on the iOS side that we should avoid introducing into Android for the sake of parity. The onMomentumScrollEnd
event should only fire after onMomentumScrollBegin
, driven by a user-activated fling or animated scrollTo
@@ -733,7 +734,6 @@ public void run() { | |||
mPostTouchRunnable = null; | |||
if (mSendMomentumEvents) { | |||
ReactScrollViewHelper.emitScrollMomentumEndEvent(ReactScrollView.this); | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mSendMomentumEvents
should only be used to guard from emitting events to JS, the NativeAnimatedModule
should still receive scroll end here regardless (and FPS listener disabled)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
? could you brief this up and what should i do, i seems to have lost context of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The brace should be added back here and the if block should only contain the event emit, not the few lines that follow it.
...ve/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java
Outdated
Show resolved
Hide resolved
...ve/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java
Outdated
Show resolved
Hide resolved
...ve/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java
Outdated
Show resolved
Hide resolved
...react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java
Outdated
Show resolved
Hide resolved
...react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java
Outdated
Show resolved
Hide resolved
thanks for the review, will need to take a look and remember since its been a while i wrote the fixes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have introduced a few changes
- A boolean flag mMomentumScrollBeginFired is introduced to track whether onMomentumScrollBegin has been fired.
- The handleSmoothScrollMomentumEvents method checks this flag before emitting the onMomentumScrollEnd event.
- The fling method is overridden to set this flag to true when onMomentumScrollBegin is fired.
@@ -926,6 +927,7 @@ private void handlePostTouchScrolling(int velocityX, int velocityY) { | |||
} | |||
|
|||
if (mSendMomentumEvents) { | |||
enableFpsListener(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall i just remove them as far as i can remember they are for per monitoring.
…react/views/scroll/ReactScrollView.java Co-authored-by: Peter Abbondanzo <peter@abbondanzo.com>
…react/views/scroll/ReactScrollView.java Co-authored-by: Peter Abbondanzo <peter@abbondanzo.com>
Oops i see we have a fling method already, i have losed a lot of context with the code actually, so any extra help is appreciated on the requests raised. |
I can reimport this PR in its current state and make a few modifications internally. If you want to reintroduce FPS listener stuffs, it can go in a separate PR if you're okay with that. |
@Abbondanzo has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
@Abbondanzo sorry for the late reply, sure that works , we can introduce the FPS listener stuff on a seperate PR mentioning the same PR, so we can keep track of the same rest i shall revert it back to where we did not had the fling override? i see you imported the PR again so let me know how can i make this easy for you to make modifications internally. |
@Biki-das It's okay as-is. After taking a closer look into how we perform animations for smooth scrolling, I'm exploring moving this all into Lines 392 to 410 in 0ee963e
This way, we need not maintain a runnable in each scroll view class and we don't have to manually invoke the smooth scroll helper in each callsite. Also, it ensures momentum scroll events are properly fired for scroll views that use pagination (which privately invoke smooth scroll via fling under the hood). |
wow, that's a good approach i see, By centralising this functionality, we can avoid duplication, improve consistency, and ensure momentum scroll events are properly fired even for pagination-based scroll views. I am happy to see this fix being landed, it bugged me off few months back on the product experience, trying to do a specific feature and not being able to do it, and i felt, this is not just limited to me, a lot of other devs would also get bitten of this, so thank you for helping us out there, means a lot ❤️. |
@Abbondanzo merged this pull request in c69e330. |
This pull request was successfully merged by @Biki-das in c69e330 When will my fix make it into a release? | How to file a pick request? |
Summary: in iOS on a scroll generated programatically, the `onMomentScrollEnd` is fired, though in case of android the same does not happen, this PR tries to implement the same behaviour for android as well, while diving through the code it seems we have two extra `onMomentumScrollEnd` events. Only one event should be fired. **iOS Behaviour on Programmatic Scroll** https://github.com/facebook/react-native/assets/72331432/fb8f16b1-4db6-49fe-83a1-a1c40bf49705 https://github.com/facebook/react-native/assets/72331432/9842f522-b616-4fb3-b197-40817f4aa9cb **Android Behaviour on Programmatic Scroll** https://github.com/facebook/react-native/assets/72331432/c24d3f06-4e2a-4bef-81af-d9227a3b1a4a https://github.com/facebook/react-native/assets/72331432/d4917843-730b-4bd7-90d9-33efb0f471a7 If closely observed we can see the `onMomentumScrollEnd` does not gets called in Android unlike to iOS. [Android][Fixed] - Dispatch onMomentumScrollEnd after programmatic scrolling Pull Request resolved: #45187 Test Plan: i have added updates to the FlatList example and ScrollViewSimple here is a ScreenRecording of `onMomentumScrollEnd` firing in android after the code changes https://github.com/facebook/react-native/assets/72331432/f036d1a5-6ebf-47ba-becd-4db98a406b15 https://github.com/facebook/react-native/assets/72331432/8c788c39-3392-4822-99c5-6e320398714b Reviewed By: javache Differential Revision: D65539724 Pulled By: Abbondanzo fbshipit-source-id: f3a5527ac5979f5ec0c6ae18d80fdc20c9c9c14b
This pull request was successfully merged by @Biki-das in abbe117 When will my fix make it into a release? | How to file a pick request? |
Summary:
in iOS on a scroll generated programatically, the
onMomentScrollEnd
is fired, though in case of android the same does not happen, this PR tries to implement the same behaviour for android as well, while diving through the code it seems we have two extraonMomentumScrollEnd
events. Only one event should be fired.iOS Behaviour on Programmatic Scroll
Screen.Recording.2024-06-26.at.8.18.46.PM.mov
Screen.Recording.2024-06-26.at.8.50.00.PM.mov
Android Behaviour on Programmatic Scroll
Screen.Recording.2024-06-26.at.8.19.28.PM.mov
Screen.Recording.2024-06-26.at.8.51.15.PM.mov
If closely observed we can see the
onMomentumScrollEnd
does not gets called in Android unlike to iOS.Changelog:
[Android] [Fixed] - fix onMomentum scroll end similar to iOS
Test Plan:
i have added updates to the FlatList example and ScrollViewSimple
here is a ScreenRecording of
onMomentumScrollEnd
firing in android after the code changesScreen.Recording.2024-06-26.at.8.12.08.PM.mov
Screen.Recording.2024-06-26.at.8.41.55.PM.mov