From 90cb45f1eb905a5565e31b901f22052acb90d007 Mon Sep 17 00:00:00 2001 From: Igor Mandrigin Date: Thu, 15 Nov 2018 07:13:41 -0800 Subject: [PATCH] Workaround a wrong fling direction for inverted ScrollViews on Android P (#21117) Summary: This is a safe workaround to an issue in Android P: https://issuetracker.google.com/issues/112385925 It is based on a fact that even though `fling` receive a wrong sign in `velocityY`, `mOnScrollDispatchHelper.getYFlingVelocity()` still returns a fling direction. Fixes #19434 Pull Request resolved: https://github.com/facebook/react-native/pull/21117 Differential Revision: D13082740 Pulled By: hramos fbshipit-source-id: 1b28586d2c7bdcae4a111d3cead4a0455cebb99a --- .../react/views/scroll/ReactScrollView.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index e31a84e0576dc1..1bffae3123ddf8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -299,8 +299,18 @@ public void getClippingRect(Rect outClippingRect) { @Override public void fling(int velocityY) { + // Workaround. + // On Android P if a ScrollView is inverted, we will get a wrong sign for + // velocityY (see https://issuetracker.google.com/issues/112385925). + // At the same time, mOnScrollDispatchHelper tracks the correct velocity direction. + // + // Hence, we can use the absolute value from whatever the OS gives + // us and use the sign of what mOnScrollDispatchHelper has tracked. + final int correctedVelocityY = (int)(Math.abs(velocityY) * Math.signum(mOnScrollDispatchHelper.getYFlingVelocity())); + + if (mPagingEnabled) { - flingAndSnap(velocityY); + flingAndSnap(correctedVelocityY); } else if (mScroller != null) { // FB SCROLLVIEW CHANGE @@ -316,7 +326,7 @@ public void fling(int velocityY) { getScrollX(), // startX getScrollY(), // startY 0, // velocityX - velocityY, // velocityY + correctedVelocityY, // velocityY 0, // minX 0, // maxX 0, // minY @@ -329,9 +339,9 @@ public void fling(int velocityY) { // END FB SCROLLVIEW CHANGE } else { - super.fling(velocityY); + super.fling(correctedVelocityY); } - handlePostTouchScrolling(0, velocityY); + handlePostTouchScrolling(0, correctedVelocityY); } private void enableFpsListener() {