From 32cb9ec49c801fcebe61486149134ab542d9364b Mon Sep 17 00:00:00 2001 From: Davide Mainas Date: Fri, 1 Feb 2019 03:59:23 -0800 Subject: [PATCH] Fix Inverted Horizontal ScrollView on Android (#23233) Summary: ScrollView (as well as FlatList) used with horizontal={true} and inverted={true} do not scroll as expected due to a known Android P bug. Fixes #22710. This is pretty much a clone of PR #21117, applied to a horizontal ScrollView. [Android] [Fixed] - Fix Inverted Horizontal ScrollView on Android 1. Create a test application with a FlatList with horizontal={true} inverted={true}. 2. Fill it with data 3. Scroll and release your finger Pull Request resolved: https://github.com/facebook/react-native/pull/23233 Differential Revision: D13915911 Pulled By: cpojer fbshipit-source-id: d32c82e6d9076f5ffdf342fcd71bd921e9c8a97b --- .../scroll/ReactHorizontalScrollView.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index bf6c3bd51a1554..973421db6cbce3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -286,8 +286,18 @@ public boolean onTouchEvent(MotionEvent ev) { @Override public void fling(int velocityX) { + + // Workaround. + // On Android P if a ScrollView is inverted, we will get a wrong sign for + // velocityX (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 correctedVelocityX = (int)(Math.abs(velocityX) * Math.signum(mOnScrollDispatchHelper.getXFlingVelocity())); + if (mPagingEnabled) { - flingAndSnap(velocityX); + flingAndSnap(correctedVelocityX); } else if (mScroller != null) { // FB SCROLLVIEW CHANGE @@ -302,7 +312,7 @@ public void fling(int velocityX) { mScroller.fling( getScrollX(), // startX getScrollY(), // startY - velocityX, // velocityX + correctedVelocityX, // velocityX 0, // velocityY 0, // minX Integer.MAX_VALUE, // maxX @@ -316,9 +326,9 @@ public void fling(int velocityX) { // END FB SCROLLVIEW CHANGE } else { - super.fling(velocityX); + super.fling(correctedVelocityX); } - handlePostTouchScrolling(velocityX, 0); + handlePostTouchScrolling(correctedVelocityX, 0); } @Override