Skip to content
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] ScrollView momentum not stopping when calling scrollTo programmatically #32235

Closed
chr-sk opened this issue Sep 20, 2021 · 10 comments
Closed

Comments

@chr-sk
Copy link

chr-sk commented Sep 20, 2021

Description

When scrolling down a long ScrollView or FlatList on Android and calling scrollTo programmatically while the ScrollView's momentum is still going, the momentum does not stop and the resulting scrolling is stuttering and simply wrong.

React Native version / Platform

0.65.1 / Android

With 0.63.4, this bug was not yet present.

Steps To Reproduce

  1. Render a ScrollView (or FlatList) with long content and a button with onPress={() => scrollViewRef.scrollTo({ y: 0, animated: true })}.
  2. Scroll quickly down with your finger so that a momentum occurs.
  3. Press the button while the momentum is still going.

Expected Results

The momentum should stop and the ScrollView should scroll to its beginning.

Possible reason

It seems that the reason for this bug lies in the following commit: 10314fe

@reepush
Copy link
Contributor

reepush commented Nov 29, 2021

10314fe made scrolling worse on Android :(

@yiuyiu
Copy link

yiuyiu commented Jan 11, 2022

Running into the same issue.

@RosCoder
Copy link

React Native 0.70.6. The same issue..

@bolan9999
Copy link

Any update? fk rn

@moremorefun
Copy link

scrollViewRef.scrollTo({ y: xxx, animated: false})

Nor did it move to the specified location, the new target location did not overwrite the old target location

@anatoleblanc
Copy link

Would love to have an update on this :)

@stitesExpensify
Copy link

I would also appreciate an update if anyone has found a solution

@halftheopposite
Copy link

halftheopposite commented Feb 7, 2023

This is also something we are facing on Android only (RN 0.70.1), and for a little bit more context:

  1. Scroll down fast
  2. onScroll reports normal scrolling values (ex: 1200, 1220, 1240, etc.)
  3. Trigger a scrollTo to y: 0 with an outside action
  4. onScroll correctly reports a scroll of y: 0 once, but then continues with its momentum (ex: 1240, 0, 1260, 1280, etc.)

@moremorefun
Copy link

This is also something we are facing, and for a little bit more context:

  1. Scroll down fast

  2. onScroll reports normal scrolling values (ex: 1200, 1220, 1240, etc.)

  3. Trigger a scrollTo to y: 0 with an outside action

  4. onScroll correctly reports a scroll of y: 0 once, but then continues with its momentum (ex: 1240, 0, 1260, 1280, etc.)

same issue

@tomekzaw
Copy link
Contributor

tomekzaw commented Feb 7, 2023

The issue still persists on 0.71.2, both on Android emulator as well as physical device.

I've made a repro: https://github.com/tomekzaw/Issue32235

Here's a video recording:

recording.mov

I will investigate this issue further.

Edit: As a workaround, you can use scrollTo function from react-native-reanimated: tomekzaw/Issue32235@81f34c4 Note that it only works for animated: true (smooth scroll), for animated: false (immediate scroll) the issue still persists.

workaround.mov

Edit: After many hours of debugging, I came up with the following change that seems to resolve the issue. I will submit a pull request with this change soon.

   public void scrollTo(int x, int y) {
+    mScroller.abortAnimation();
     super.scrollTo(x, y);
     ReactScrollViewHelper.updateFabricScrollState(this);
     setPendingContentOffsets(x, y);
   }
fixed.mov

OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this issue May 22, 2023
…ically (facebook#36104)

Summary:
Fixes facebook#32235.

See facebook#32235 (comment) for details.

Before:

https://user-images.githubusercontent.com/20516055/217268275-7ec9a228-bbd6-4294-aa1f-a43c4268984c.mov

After:

https://user-images.githubusercontent.com/20516055/217786242-f44b008f-6c6d-4f11-a7bd-b7a01150f3fb.mov

## Changelog

[ANDROID] [FIXED] - Fixed ScrollView momentum not stopping when calling scrollTo programmatically

Pull Request resolved: facebook#36104

Test Plan: Reproducer: https://github.com/tomekzaw/Issue32235/blob/master/App.tsx

Reviewed By: christophpurrer

Differential Revision: D43153500

Pulled By: cortinico

fbshipit-source-id: ac9c5ed754ed8ba72fe45d506c76f52d795dc83e
facebook-github-bot pushed a commit that referenced this issue Aug 2, 2023
…inside a KeyboardAvoidingView (#38728)

Summary:
Starting from RN 0.72.0, when we nest a ScrollView inside a KeyboardAvoidingView, the ScrollView doesn't respond properly to the Keyboard on Android.

https://github.com/facebook/react-native/assets/32062066/a62b5a42-6817-4093-91a2-7cc9e4a315bb

This issue is due to a change made in #36104, which was added to fix #32235.

That commit changed this line of code to abort the Scroller animation if a new call to the `scrollTo` method was made:

https://github.com/facebook/react-native/blob/aab52859a447a8257b106fe307008af218322e3d/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java#L1073

Apparently, this is the same method that scrolls the ScrollView in response to the Keyboard opening on Android.

So, here comes my proposal for a fix that doesn't break #36104 and fixes #38152.

When we open the Keyboard, the call stack is as follows:
- InputMethodManager
- AndroidIME
- InsetsController
- `ReactScrollView.scrollTo` gets called

When we use the ScrollView method `scrollTo` directly from the UI, the call stack is different as it goes through:
- ReactScrollViewCommandHelper
- ReactScrollViewManager
- `ReactScrollView.scrollTo` gets called

We can move `mScroller.abortAnimation();` from `ReactScrollView.scrollTo` to the `ReactScrollViewManager.scrollTo` method so that it gets called only when we call `scrollTo` from the UI and not when the `scrollTo` method is called by other sources.

https://github.com/facebook/react-native/assets/32062066/9c10ded3-08e5-48e0-9a85-0987d62de011

## Changelog:

[ANDROID] [FIXED] - Fixed ScrollView not responding to Keyboard events when nested inside a KeyboardAvoidingView

Pull Request resolved: #38728

Test Plan: You can see the issue and the proposed fixes in this repo: [kav-test-android](https://github.com/andreacassani/kav-test-android). Please refer to the `kav_test_fix` folder and to the [readme](https://github.com/andreacassani/kav-test-android/blob/main/README.md).

Reviewed By: NickGerleman

Differential Revision: D47972445

Pulled By: ryancat

fbshipit-source-id: e58758d4b3d5318b947b42a88a56ad6ae69a539c
lunaleaps pushed a commit that referenced this issue Aug 7, 2023
…inside a KeyboardAvoidingView (#38728)

Summary:
Starting from RN 0.72.0, when we nest a ScrollView inside a KeyboardAvoidingView, the ScrollView doesn't respond properly to the Keyboard on Android.

https://github.com/facebook/react-native/assets/32062066/a62b5a42-6817-4093-91a2-7cc9e4a315bb

This issue is due to a change made in #36104, which was added to fix #32235.

That commit changed this line of code to abort the Scroller animation if a new call to the `scrollTo` method was made:

https://github.com/facebook/react-native/blob/aab52859a447a8257b106fe307008af218322e3d/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java#L1073

Apparently, this is the same method that scrolls the ScrollView in response to the Keyboard opening on Android.

So, here comes my proposal for a fix that doesn't break #36104 and fixes #38152.

When we open the Keyboard, the call stack is as follows:
- InputMethodManager
- AndroidIME
- InsetsController
- `ReactScrollView.scrollTo` gets called

When we use the ScrollView method `scrollTo` directly from the UI, the call stack is different as it goes through:
- ReactScrollViewCommandHelper
- ReactScrollViewManager
- `ReactScrollView.scrollTo` gets called

We can move `mScroller.abortAnimation();` from `ReactScrollView.scrollTo` to the `ReactScrollViewManager.scrollTo` method so that it gets called only when we call `scrollTo` from the UI and not when the `scrollTo` method is called by other sources.

https://github.com/facebook/react-native/assets/32062066/9c10ded3-08e5-48e0-9a85-0987d62de011

## Changelog:

[ANDROID] [FIXED] - Fixed ScrollView not responding to Keyboard events when nested inside a KeyboardAvoidingView

Pull Request resolved: #38728

Test Plan: You can see the issue and the proposed fixes in this repo: [kav-test-android](https://github.com/andreacassani/kav-test-android). Please refer to the `kav_test_fix` folder and to the [readme](https://github.com/andreacassani/kav-test-android/blob/main/README.md).

Reviewed By: NickGerleman

Differential Revision: D47972445

Pulled By: ryancat

fbshipit-source-id: e58758d4b3d5318b947b42a88a56ad6ae69a539c
Kudo pushed a commit to expo/react-native that referenced this issue Aug 21, 2023
…inside a KeyboardAvoidingView (facebook#38728)

Summary:
Starting from RN 0.72.0, when we nest a ScrollView inside a KeyboardAvoidingView, the ScrollView doesn't respond properly to the Keyboard on Android.

https://github.com/facebook/react-native/assets/32062066/a62b5a42-6817-4093-91a2-7cc9e4a315bb

This issue is due to a change made in facebook#36104, which was added to fix facebook#32235.

That commit changed this line of code to abort the Scroller animation if a new call to the `scrollTo` method was made:

https://github.com/facebook/react-native/blob/aab52859a447a8257b106fe307008af218322e3d/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java#L1073

Apparently, this is the same method that scrolls the ScrollView in response to the Keyboard opening on Android.

So, here comes my proposal for a fix that doesn't break facebook#36104 and fixes facebook#38152.

When we open the Keyboard, the call stack is as follows:
- InputMethodManager
- AndroidIME
- InsetsController
- `ReactScrollView.scrollTo` gets called

When we use the ScrollView method `scrollTo` directly from the UI, the call stack is different as it goes through:
- ReactScrollViewCommandHelper
- ReactScrollViewManager
- `ReactScrollView.scrollTo` gets called

We can move `mScroller.abortAnimation();` from `ReactScrollView.scrollTo` to the `ReactScrollViewManager.scrollTo` method so that it gets called only when we call `scrollTo` from the UI and not when the `scrollTo` method is called by other sources.

https://github.com/facebook/react-native/assets/32062066/9c10ded3-08e5-48e0-9a85-0987d62de011

## Changelog:

[ANDROID] [FIXED] - Fixed ScrollView not responding to Keyboard events when nested inside a KeyboardAvoidingView

Pull Request resolved: facebook#38728

Test Plan: You can see the issue and the proposed fixes in this repo: [kav-test-android](https://github.com/andreacassani/kav-test-android). Please refer to the `kav_test_fix` folder and to the [readme](https://github.com/andreacassani/kav-test-android/blob/main/README.md).

Reviewed By: NickGerleman

Differential Revision: D47972445

Pulled By: ryancat

fbshipit-source-id: e58758d4b3d5318b947b42a88a56ad6ae69a539c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants