From 1a9e2d5d5589ce5cee92868ea5bccceb6e161eff Mon Sep 17 00:00:00 2001 From: Xin Chen Date: Fri, 8 Oct 2021 18:56:09 -0700 Subject: [PATCH] Fix issue with scrollTo method in ScrollViews to set actual scroll position Summary: The `scrollTo` method in ScrollViews are using the `(x, y)` position they got from upperstream to scroll, and to set the state for Fabric. This diff fixes an edge case where the scroll result is not ended up to `(x, y)`. For example, if we are going to scroll to the last item in the list, the item may not scroll to the `(x, y)` position, but stay at the end position of the view. - Change `scrollTo` method to use the actual `scrollX` and `scrollY` position after scrolling to set current state. Changelog: [Android][Fixed] - scrollTo API in ScrollView will check the actual scroll position before setting the scroll state Reviewed By: JoshuaGross Differential Revision: D31492685 fbshipit-source-id: e5513fb735ea68c5014b5c47fadffe461cad5c94 --- .../react/views/scroll/ReactHorizontalScrollView.java | 8 ++++++-- .../com/facebook/react/views/scroll/ReactScrollView.java | 8 ++++++-- 2 files changed, 12 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 82099cb25b6b03..470c7d0f9bff70 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 @@ -1231,8 +1231,12 @@ public void scrollTo(int x, int y) { } super.scrollTo(x, y); - updateStateOnScroll(x, y); - setPendingContentOffsets(x, y); + // The final scroll position might be different from (x, y). For example, we may need to scroll + // to the last item in the list, but that item cannot be move to the start position of the view. + final int actualX = getScrollX(); + final int actualY = getScrollY(); + updateStateOnScroll(actualX, actualY); + setPendingContentOffsets(actualX, actualY); } /** 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 3b920a6f505b80..54643e6e2da4b5 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 @@ -1006,8 +1006,12 @@ public void onAnimationRepeat(Animator animator) {} @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); - updateStateOnScroll(x, y); - setPendingContentOffsets(x, y); + // The final scroll position might be different from (x, y). For example, we may need to scroll + // to the last item in the list, but that item cannot be move to the start position of the view. + final int actualX = getScrollX(); + final int actualY = getScrollY(); + updateStateOnScroll(actualX, actualY); + setPendingContentOffsets(actualX, actualY); } /**