Fix Android ScrollView not responding to Keyboard events when nested 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 https://github.com/facebook/react-native/issues/36104, which was added to fix https://github.com/facebook/react-native/issues/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 https://github.com/facebook/react-native/issues/36104 and fixes https://github.com/facebook/react-native/issues/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: https://github.com/facebook/react-native/pull/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
This commit is contained in:
Andrea Cassani
2023-08-01 20:21:04 -07:00
committed by Facebook GitHub Bot
parent 7c79e3107f
commit c616148a05
2 changed files with 7 additions and 1 deletions
@@ -218,6 +218,12 @@ public class ReactScrollView extends ScrollView
}
}
public void abortAnimation() {
if (mScroller != null && !mScroller.isFinished()) {
mScroller.abortAnimation();
}
}
public void setSnapInterval(int snapInterval) {
mSnapInterval = snapInterval;
}
@@ -1070,7 +1076,6 @@ public class ReactScrollView extends ScrollView
*/
@Override
public void scrollTo(int x, int y) {
mScroller.abortAnimation();
super.scrollTo(x, y);
ReactScrollViewHelper.updateFabricScrollState(this);
setPendingContentOffsets(x, y);
@@ -213,6 +213,7 @@ public class ReactScrollViewManager extends ViewGroupManager<ReactScrollView>
@Override
public void scrollTo(
ReactScrollView scrollView, ReactScrollViewCommandHelper.ScrollToCommandData data) {
scrollView.abortAnimation();
if (data.mAnimated) {
scrollView.reactSmoothScrollTo(data.mDestX, data.mDestY);
} else {