react-native: Inverted FlatList doesn't work on Android P

When using FlatList with inverted={true} the scrolling doesn’t work as expected. it seems that the momentum is not inverted, and at the end of the scroll - the momentum takes it back to the other side

Environment

Environment: OS: macOS High Sierra 10.13.4 Node: 8.11.1 Yarn: 1.5.1 npm: 5.6.0 Watchman: 4.9.0 Xcode: Xcode 9.3 Build version 9E145 Android Studio: 3.1 AI-173.4670197

Packages: (wanted => installed) react: 16.3.1 => 16.3.1 react-native: ~0.55.2 => 0.55.4

Steps to Reproduce

With Android P public beta installed - https://snack.expo.io/BklXgV8Nk7

Expected Behavior

scrolling will work as usual

Actual Behavior

momentum is inverted

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 47
  • Comments: 36 (1 by maintainers)

Commits related to this issue

Most upvoted comments

So I’ve been digging into this a bit more and have landed on this line:

https://github.com/facebook/react-native/blob/8f7372fe1b8517848b8d35ded2b07c74adb3d574/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java#L265

Seems that thevelocityY thats coming in is negative when the FlatList is inverted and you fling to scroll up causing the list to start to scroll up but then shoot back down. Was able to patch the issue by setting velocityY = velocityY * -1; within the if statement. Obviously not a real fix but hopeful that it at least sheds some light on what may be the cause. Going to continue diving in to see if I can chase it down.

@kelset I tried to make a workaround as safe as possible and w/o having to check for a build number: https://github.com/facebook/react-native/pull/21117/files That fixed the issue for us.

I will be happy to hear your feedback!

Is there any chance of this PR being merged before the next release?

I used a similar workaround to @Rongrs by checking this.getScaleY() < 0 and Build.VERSION in https://github.com/facebook/react-native/blob/0.54-stable/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java#L270

  @Override
  public void fling(int velocityY) {
    if (mScroller != null) {
      // FB SCROLLVIEW CHANGE

      // We provide our own version of fling that uses a different call to the standard OverScroller
      // which takes into account the possibility of adding new content while the ScrollView is
      // animating. Because we give essentially no max Y for the fling, the fling will continue as long
      // as there is content. See #onOverScrolled() to see the second part of this change which properly
      // aborts the scroller animation when we get to the bottom of the ScrollView content.

      int scrollWindowHeight = getHeight() - getPaddingBottom() - getPaddingTop();

      if (this.getScaleY() < 0 && Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) {
        velocityY *= -1;
      }

      mScroller.fling(
        getScrollX(),
        getScrollY(),
        0,
        velocityY,
        0,
        0,
        0,
        Integer.MAX_VALUE,
        0,
        scrollWindowHeight / 2);

      postInvalidateOnAnimation();

      // END FB SCROLLVIEW CHANGE
    } else {
      super.fling(velocityY);
    }

Reproducible on release version of Android P

hey sorry, I completely missed all notifications about this lately 🤦‍♂️

I’ll double check the PR and we’ll try to get it in asap (but probably won’t be next patch for 0.57.x, we’ll see - if not it will be in the one after that).

@roylabanon it isn’t super trivial, but that is how we did it. Here is our RN fork (with the branch containing the fix): https://github.com/status-im/react-native/tree/status-0.56-1 And here is the PR that tweaks all the project settings: https://github.com/status-im/status-react/pull/4981/files

Note, that apart from that you will need to setup your dev environment (install Android NDK, etc), but that is very well described in the official docs (as @johakr mentioned).

@scottmas you can check the changelog to know which commits landed and which not.

You can also suggest commits that landed to be cherry picked in the dedicated issue - in particular, this commit has already been requested.

0.57.7 looks like fixed!

@roylabanon You need to build react-native from source in order to make any android changes take effect. Maintaining a fork of react-native isn’t as trivial as forking the github repo and commiting your local changes. It always involves an additional building step, at least for android. Good luck.

@roylabanon the easiest way is to use a fork of React Native and apply the patch there.

Having a fork might be useful for other things as well (let’s say you need to expose a property that RN doesn’t expose by default, etc).

@Rongrs @jarredwitt @krishom Could you please explain, how are you using overridden ReactScrollView.java class with your app? Are you creating a custom build of react-native .aar file?

@kelset I tried to make a workaround as safe as possible and w/o having to check for a build number: https://github.com/facebook/react-native/pull/21117/files That fixed the issue for us.

I will be happy to hear your feedback!

Reproducible also on native android app (example), with scrollView and scaleY=-1 same app don’t have the problem on Oreo devices.

so it may be a native issue, and possibly related to this: https://developer.android.com/about/versions/pie/android-9.0-changes-28#scrolling-element ?