From c616148a05c00728b80d2fd9dcbd6f15d08a2dfa Mon Sep 17 00:00:00 2001 From: Andrea Cassani <32062066+andreacassani@users.noreply.github.com> Date: Tue, 1 Aug 2023 20:21:04 -0700 Subject: [PATCH] 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 --- .../com/facebook/react/views/scroll/ReactScrollView.java | 7 ++++++- .../react/views/scroll/ReactScrollViewManager.java | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 86d9dafffe2d67..5ed6093fa0c99f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -218,6 +218,12 @@ public void setDecelerationRate(float decelerationRate) { } } + public void abortAnimation() { + if (mScroller != null && !mScroller.isFinished()) { + mScroller.abortAnimation(); + } + } + public void setSnapInterval(int snapInterval) { mSnapInterval = snapInterval; } @@ -1070,7 +1076,6 @@ public void reactSmoothScrollTo(int x, int y) { */ @Override public void scrollTo(int x, int y) { - mScroller.abortAnimation(); super.scrollTo(x, y); ReactScrollViewHelper.updateFabricScrollState(this); setPendingContentOffsets(x, y); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index b41b0858f6f83b..33658e78788eeb 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -213,6 +213,7 @@ public void flashScrollIndicators(ReactScrollView scrollView) { @Override public void scrollTo( ReactScrollView scrollView, ReactScrollViewCommandHelper.ScrollToCommandData data) { + scrollView.abortAnimation(); if (data.mAnimated) { scrollView.reactSmoothScrollTo(data.mDestX, data.mDestY); } else {