From 9b2f1e943eb453d1685b9e29c4338ba641531fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Nikkil=C3=A4?= Date: Tue, 25 Sep 2018 14:08:01 +0300 Subject: [PATCH] Fix Android momentum scroll differences to iOS - Momentum scroll events should not be emitted when there's no momentum - Momentum scroll should be interrupted by a drag, which should not emit an onMomentumScrollEnd event. Instead a new momentum scroll should begin once dragging ends. --- .../views/scroll/ReactHorizontalScrollView.java | 12 ++++++++++++ .../facebook/react/views/scroll/ReactScrollView.java | 12 ++++++++++++ 2 files changed, 24 insertions(+) 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 566b6018b02e1f..b71a654ecd9d0a 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 @@ -246,6 +246,12 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { ReactScrollViewHelper.emitScrollBeginDragEvent(this); mDragging = true; enableFpsListener(); + // The user might be interrupting a fling/snap and we need to cancel any ongoing animations. + // Mirrors behaviour on iOS by starting a new momentum scroll event series after this drag. + if (mPostTouchRunnable != null) { + removeCallbacks(mPostTouchRunnable); + mPostTouchRunnable = null; + } return true; } } catch (IllegalArgumentException e) { @@ -445,6 +451,12 @@ private void handlePostTouchScrolling(int velocityX, int velocityY) { return; } + // Don't emit momentum events if there's not going to be a momentum scroll, mirrors iOS momentum + // scroll behaviour. + if (!mPagingEnabled && velocityX == 0 && velocityY == 0) { + return; + } + // Check if we are already handling this which may occur if this is called by both the touch up // and a fling call if (mPostTouchRunnable != null) { 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 d99d878de4ce99..12b8015cfda8db 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 @@ -235,6 +235,12 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { ReactScrollViewHelper.emitScrollBeginDragEvent(this); mDragging = true; enableFpsListener(); + // The user might be interrupting a fling/snap and we need to cancel any ongoing animations. + // Mirrors behaviour on iOS by starting a new momentum scroll event series after this drag. + if (mPostTouchRunnable != null) { + removeCallbacks(mPostTouchRunnable); + mPostTouchRunnable = null; + } return true; } } catch (IllegalArgumentException e) { @@ -412,6 +418,12 @@ private void handlePostTouchScrolling(int velocityX, int velocityY) { return; } + // Don't emit momentum events if there's not going to be a momentum scroll, mirrors iOS momentum + // scroll behaviour. + if (!mPagingEnabled && velocityX == 0 && velocityY == 0) { + return; + } + // Check if we are already handling this which may occur if this is called by both the touch up // and a fling call if (mPostTouchRunnable != null) {