Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.57.0] Horizontal scroll view + pagingEnabled / snapToInterval / snapToOffsets #21116

Closed
3 tasks done
mjmasn opened this issue Sep 14, 2018 · 46 comments
Closed
3 tasks done
Labels
Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Resolution: Locked This issue was locked by the bot.

Comments

@mjmasn
Copy link
Contributor

mjmasn commented Sep 14, 2018

Environment

Run react-native info in your terminal and paste its contents here.

  React Native Environment Info:
    System:
      OS: Linux 4.15 Ubuntu 16.04.5 LTS (Xenial Xerus)
      CPU: x64 Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
      Memory: 638.66 MB / 15.54 GB
      Shell: 4.3.48 - /bin/bash
    Binaries:
      Node: 8.11.0 - ~/.nvm/versions/node/v8.11.0/bin/node
      Yarn: 1.9.4 - /usr/bin/yarn
      npm: 5.6.0 - ~/.nvm/versions/node/v8.11.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      Android SDK:
        Build Tools: 23.0.1, 26.0.1, 26.0.2, 26.0.3, 27.0.0, 27.0.3
        API Levels: 16, 19, 22, 23, 26, 27, 28
    IDEs:
      Android Studio: 3.1 AI-173.4907809
    npmPackages:
      react: ^16.5.0 => 16.5.1 
      react-native: 0.57.0 => 0.57.0 
    npmGlobalPackages:
      create-react-native-app: 1.0.0
      react-native-cli: 2.0.1
      react-native-git-upgrade: 0.2.7

Description

This is a major regression from 0.56.

The changes to paging and snapping in horizontal scroll views appear to have totally broken the UX in android.

Previously swiping worked pretty much like ViewPagerAndroid and swiped a single page at a time if you swiped at least 50% of the screen width (not sure of exact figure), and the speed of the animation roughly matched the speed of the swipe. It was possible to rapidly swipe through a set of pages with quick swipes.

Now the slightest touch scrolls 1 or more pages (usually 2 for a 'normal' swipe) with a really slow animation and it's not possible to swipe through pages rapidly (swiping quickly just makes the animation slow down even more).

It also looks like you can scroll fast if swiping "back" (i.e. finger moving left to right on the screen) but not in a controlled way.

The new snapToOffsets is also broken.

Reproducible Demo

Let us know how to reproduce the issue. Include a code sample, share a project, or share an app that reproduces the issue using https://snack.expo.io/. Please follow the guidelines for providing a MCVE: https://stackoverflow.com/help/mcve

I created identical repos for 0.56.1 and 0.57.0 with toggles to turn pagingEnabled, snapToInterval, snapToOffsets on/off. Doesn't seem to be any combination that works in 0.57.0.

https://github.com/mjmasn/OldSwipe (RN 0.56.1 behaviour)
https://github.com/mjmasn/NewSwipe (RN 0.57.0 behaviour)

For each repo:

  1. Clone repo
  2. Run yarn
  3. Run yarn start and react-native run-android.
  4. Toggle options on/off with the top row of buttons, then try swiping left and right.

BTW for NewSwipe the app seems to crash in native code when toggling snapToOffsets off 🤔

@react-native-bot react-native-bot added the Platform: Linux Building on Linux. label Sep 14, 2018
@mjmasn

This comment has been minimized.

@nadavmos
Copy link

was ok on 0.57.0-rc.3, broke in rc.4

@kelset kelset added 🔶Lists and removed Platform: Linux Building on Linux. labels Sep 17, 2018
@kelset
Copy link
Contributor

kelset commented Sep 17, 2018

@nadavmos are you able to pinpoint which commit may be responsible for this?

We also have a few issues related to *Lists and they seem to be related to these commits, but not sure if they are the reason why OP is having issues:

Could you test a patch/fork that reverse them and let me know if the issue disappear @mjmasn ?

@mjmasn
Copy link
Contributor Author

mjmasn commented Sep 18, 2018

@kelset problem is with <ScrollView horizontal /> not <*List /> although they may well be affected too. Looks like the main change between rc.3 and rc.4 was this commit: ef7e99c which looks like it touches a lot of scroll view related code. Maybe @olegbl can shed some light?

@olegbl
Copy link
Contributor

olegbl commented Sep 19, 2018

I can help shed some light, yes. I fixed the swipe-scrolling algorithm when I added snapToOffsets.

Previously, it was using smoothScrollTo() for everything. There were two main issues:

  1. smoothScrollTo() always animated over 250ms on Android. That means that velocity varied a lot between a short scroll and a long one.
  2. The calculation that tried to estimate how far the scroll would go was totally broken. It was just using velocity as a flat offset, which is completely wrong. Android's ScrollView implementation actually uses a physics-based algorithm that takes the velocity and produces an offset. (See the old algorithm here: https://goo.gl/jSZf4f)

As a result, swiping even a little bit sideways would sometimes scroll you all the way to the left/right or sometimes barely scroll you at all. It was very inconsistent and provided a poor UX. It also did not match iOS at all, which did not exhibit any such problems.

With the changes, the algorithm is now using the standard fling() function, but limiting the offset's minimum and maximum value to both be the value it should snap to. This forces Android to use the same scrolling algorithm it would use if the snapping didn't exist.

NOTE: This behavior should not match ViewPagerAndroid. A horizontal ScrollView is not meant to scroll only one snap at a time. It's meant to snap to the nearest point to where the ScrollView would scroll if there was no snapping involved. This is currently the case on both iOS and Android.

@nadavmos
Copy link

@olegbl thanks for shedding light on this, it creates a major difference between iOS and Android where in iOS when horizontal paging is enabled no matter how hard (or soft) you fling, you'll only be able to swipe one page at a time. the current behaviour of the scrollview on android is if the paging is totally ignored and its possible to manually scroll to a position between pages without being snapped to page

@mjmasn
Copy link
Contributor Author

mjmasn commented Sep 19, 2018

@olegbl do you have access to an iPhone with Facebook's F8 app installed?

That uses pagingEnabled to imitate a ViewPagerAndroid component on iOS. If you tap Schedule -> Registration (or any event), then swipe left and right you will see it matches the RN 0.56 android behaviour.

pagingEnabled

When true, the scroll view stops on multiples of the scroll view's size when scrolling. This can be used for horizontal pagination. The default value is false.

Our problem is that even if this prop did what it claims to, we need it to apply to snapToInterval / snapToOffsets as well. i.e. only ever scroll 1 page per swipe. This seemed to be the behaviour on RN 0.56 - with snapToInterval we could have views where we showed multiple 'pages' on tablet, but scrolling would still just scroll 1 'interval' at a time, and to scroll faster you just swipe repeatedly like with ViewPagerAndroid. We can't use VPA because we need to show multiple pages at a time depending on device screen width (and we're still waiting on a fix for adding/removing pages without re-rendering the whole VPA).

I'll do some more testing with iOS later when I have access to a Macbook but there is definitely a huge difference between iOS and android now, and a huge change from 0.56 -> 0.57 for android.

@mjmasn
Copy link
Contributor Author

mjmasn commented Sep 19, 2018

So it looks like we can get a not very smooth, poor man's version of the 1-page-at-a-time behaviour on Android by setting decelerationRate={0.0} (or 1.0 for some reason) but the smooth scroll is still weird. Obviously you consider it a bug in your point 1) but for paged scrolling (and even arguably for normal vertical scrolling) the smooth scroll should be constant time not constant velocity in my opinion 🤷‍♂️ Constant velocity just feels like unnecessary waiting on longer scrolls from a UX POV.

@ihor
Copy link

ihor commented Sep 19, 2018

I'm having the same issue. Any recommendations on how to make Android swipe only one page at a time?

@kelset kelset added the Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. label Sep 19, 2018
@olegbl
Copy link
Contributor

olegbl commented Sep 19, 2018

in iOS when horizontal paging is enabled no matter how hard (or soft) you fling, you'll only be able to swipe one page at a time

Ah, you're right! It looks like on iOS, the paging algorithm is indeed slightly different from the snapping algorithm and limits transition to one page at a time.

We should do that on Android as well (currently, pagingEnabled acts like snapToInterval={WIDTH_OF_SCROLLVIEW} on Android). This seems to be the major distinction that I was missing. I'll get the changes in this week. Edit: got a fix up, should be in soon-ish.

I've been going over the rest of the scenarios (snapToInterval/snapToOffsets horizontal/vertical) and they feel the same across platform but pagingEnabled does end up being different.

the paging is totally ignored and its possible to manually scroll to a position between pages without being snapped to page

I don't understand this one. If either pagingEnabled is set to true or snapToInterval/snapToOffsets are set, Android will always snap to a page boundary for me.

Our problem is that even if this prop did what it claims to, we need it to apply to snapToInterval / snapToOffsets as well.

Could you elaborate on this point a bit? I don't think I understand. As per the docs, snapToInterval just completely overrides pagingEnabled.

smooth scroll should be constant time not constant velocity in my opinion

That is not the case in the native implementation on either platform. I would think we'd want to keep the native algorithm rather than overriding it (plus the smoothScrollTo algorithm exhibited issues like #20155). Edit: for snapping just one page at a time smoothScrollTo does feel a lot better (so I'll do that for pagingEnabled).

@mjmasn
Copy link
Contributor Author

mjmasn commented Sep 19, 2018

@olegbl thanks for looking into this one, much appreciated.

Re "Could you elaborate on this point a bit?" Sure, hopefully this attempt is a bit clearer 😁 ...

The current RN 0.56 behaviour is that if we turn on pagingEnabled and snapToIncrement, swiping scrolls the view one increment at a time. Whether that's intentional or not I'm unsure but it's changed in 0.57 and the 0.56 behaviour is something we'd definitely like to keep.

The use case is basically having a set of pages where on a phone you'd see 1 page at a time, centered, with the slight edge of the prev/next page visible (hence can't just use pagingEnabled, because 'page' width != screen width). Then on tablet we'd hide the first/last 'spacer' pages and set a max width on the other pages, so you might see 3 or 4 pages across the screen, but we'd still want swiping to only move one increment at a time.

Something roughly like this (would actually be 1 view that changes some of the props/styles based on screen width, I've just split it for clarity):

// For screen width <= 320
const {width} = Dimensions.get('window');

return (
  <ScrollView horizontal pagingEnabled snapToInterval={width - 20}>
    <View style={{width: 10}} /> // For centring the other pages
    <View style={{width: width - 20}}><Text>Page 1</Text></View>
    <View style={{width: width - 20}}><Text>Page 2</Text></View>
    <View style={{width: width - 20}}><Text>Page 3</Text></View>
    <View style={{width: 10}} />
  </ScrollView>
);
// For screen width > 320
const {width} = Dimensions.get('window');

return (
  <ScrollView horizontal pagingEnabled snapToInterval={300}>
    <View style={{width: 300}}><Text>Page 1</Text></View>
    <View style={{width: 300}}><Text>Page 2</Text></View>
    <View style={{width: 300}}><Text>Page 3</Text></View>
  </ScrollView>
);

@olegbl
Copy link
Contributor

olegbl commented Sep 19, 2018

Interesting! Are you able to get this behavior on iOS as well? When I try your first snippet, I can scroll multiple pages at a time with one swipe on iOS (where the algorithm did not change).

When I was working on this, I noticed that pagingEnabled worked differently on iOS vs Android when combined with snapToInterval.

  • On iOS, snapToInterval was simply ignored when pagingEnabled was set to true: https://goo.gl/o2nRd7
  • On Android, snapToInterval was ignored unless pagingEnabled was also set to true: https://goo.gl/jub9nx
  • The documentation explicitly stated that snapToInterval overrode pagingEnabled, so that's the logic I added.

I can get the desired behavior relatively easily on iOS with just some JS code, but it's trickier on Android because apparently overflow: visible doesn't work very well on ScrollView.

Is this roughly what you are looking for? https://imgur.com/KaADzmq

If so, maybe I can just fix the overflow issue (#14416 should be possible to fix now that Android has overflow support).

Edit: I was able to make overflow: visible work on Android. Submitted a patch for that as well.

@mjmasn
Copy link
Contributor Author

mjmasn commented Sep 20, 2018

@olegbl hmm if that's the case for iOS I guess Android should match it for now, and this would be more of a feature request. Like I said it may be possible if pagingEnabled always enables the 'faster' animation regardless of whether it's overridden with snapTo* to just set the deceleration rate such that it's very unlikely to scroll more than one page at a time. I don't have a mac to hand to test right now but can do so later today.

Yep that gif is pretty much exactly what we're trying to do, nice solution too with the overflow 👍 Thanks :)

So it sounds like you've fixed or are fixing most of this already then? Do you have links to any PRs or are they FB internal at the moment? Just so we can track :)

Thanks again!

@ihor
Copy link

ihor commented Sep 20, 2018

Thanks, @olegbl! Do you have any time estimates on when the fix will be available in the repository?

@olegbl
Copy link
Contributor

olegbl commented Sep 20, 2018

Yep that gif is pretty much exactly what we're trying to do

Great, thanks!

Do you have links to any PRs or are they FB internal at the moment?

They're internal right now. I'll update this thread when they get turned into GitHub commits after being reviewed by the React Native team.

Do you have any time estimates on when the fix will be available in the repository?

Sorry, no. It depends entirely on how quickly these changes get reviewed. They should only take a few hours after that to get to GitHub.

facebook-github-bot pushed a commit that referenced this issue Sep 24, 2018
Summary:
ScrollView always clipping children on Android even when `overflow: visible` was specified.
This change just omits the clipping during draw if `overflow: visible` is passed in.
The default is not changed (from hidden to visible) in case there is a performance impact.
Android now matches iOS in behavior. This helps with issue #21116 and resolves #14416.

Reviewed By: shergin

Differential Revision: D9952096

fbshipit-source-id: 367afe33ee7ff0fdc5aa1074d239883aa289888a
@olegbl
Copy link
Contributor

olegbl commented Sep 24, 2018

The patches have made their way over to GitHub:

@rikur
Copy link

rikur commented Sep 29, 2018

The rewrite also broke inverted property on horizontal FlatList. It seems like the new code completely ignores the inverted property which results in very funky and unusable UX.

EDIT: seems to be an Android P problem instead #19434

@olegbl
Copy link
Contributor

olegbl commented Sep 30, 2018

@rikur Could you elaborate please?

  • On iOS, it didn't change any of the existing algorithms.
  • On Android, neither the previous nor the new algorithm needs to do any explicit handling of inverted ScrollViews. (At least, inverted ScrollViews worked fine for me in testing.)

Perhaps you're running into #19434 ?

@rikur
Copy link

rikur commented Sep 30, 2018

@olegbl thanks for the pointer, I was wrong assuming your changes caused the jerky behaviour.

@chrusart
Copy link
Contributor

chrusart commented Oct 1, 2018

Where patches will land? Would be nice to have it in 0.57.2, or how make them land in patch version of RN?

@kelset
Copy link
Contributor

kelset commented Oct 1, 2018

@chrusart there is a dedicated repo for Changelog & keeping up with the releases: https://github.com/react-native-community/react-native-releases

We are trying to get a 0.57.2 out today.

@olegbl
Copy link
Contributor

olegbl commented Oct 8, 2018

The scrolling can indeed feel pretty janky on Android when snapToInterval or snapToOffsets are used. That's an artifact of the implementation of Android's OverScroller.java (see adjustDuration method). I could not find a way to make it feel better. Perhaps you'll have better luck.

It certainly feels a lot better than the previous implementation (in HorizontalScrollView) though since it at least tries to maintain the velocity of the swipe. Do make sure you are using decelerationRate="fast", it makes a huge difference.

But smoothScrollAndSnap had other issues, right?

Yup, see #21116 (comment)

without padding to center item I cannot swipe to last item

You'll need to provide a repro. I have not seen this and haven't heard of anyone else encountering it either.

@kelset
Copy link
Contributor

kelset commented Oct 8, 2018

You'll need to provide a repro. I have not seen this and haven't heard of anyone else encountering it either.

related to this, please open a new issue for it too 👍

@ds8k
Copy link

ds8k commented Oct 8, 2018

Here's a video showing a horizontally scrolling FlatList on Android Pie with RN 57. The scrolling slows down as soon as my finger leaves the screen. Also shown is me unable to scroll all the way to the last item

https://www.dropbox.com/s/llu4uzs1v6efkr1/20181008_144241_edited.mp4

If I remove the snapToInterval prop then the scrolling behaves normally.

Here is a video showing that same component on RN 56:

https://www.dropbox.com/s/mrzhwp53dbs1syo/20181008_145346_edited.mp4

@olegbl
Copy link
Contributor

olegbl commented Oct 8, 2018

You'd have to provide the code for the video (the repro) and start a new issue for it :)

It very much looks like you're not using decelerationRate="fast" as suggested above. (BTW, the RN 56 video shows exactly how bad the velocity calculation is - it scrolls to practically the end of the list for even a light fling. I really wish Android had a similar way to adjust a fling's curve to what iOS does, but alas we're stuck with one of a number of bad solutions. :\ )

I think I know what's happening with the last item in your video - I'll see if I can put up a fix.

@ds8k
Copy link

ds8k commented Oct 8, 2018

@olegbl Sorry, I thought this issue encompassed the problem shown in my video as it relates to the snapToInterval being used. We are in fact using decelerationRate="fast"

I'll make a new issue if necessary, my bad.

@olegbl
Copy link
Contributor

olegbl commented Oct 8, 2018

No worries! The issue in this thread was about pagingEnabled allowing you to scroll more than one page at a time on Android.

I did repro ScrollVIew not snapping to end on Android when width != multiple of snapToInterval. Putting up a fix for that :)

For the scrolling speed - I don't think there's anything more I can do there. It's better than it was before the change (see #20155 for an example) but it's still not great. Unfortunately I don't think there's much more to be done without rewriting Android's OverScroller.java.

@chrusart
Copy link
Contributor

chrusart commented Oct 9, 2018

@olegbl I provided a snack with repro in my second comment about it, the same code also repro not scrolling to last item, just remove padding stuff and it uses decelaration 'fast', i guess this is the same as @ds8k would provide for his video.

Quick workaround would be to use smoothScroll... instead fling... when interval or offsets are used, btw. pagingEnabled is actually special case of interval (offsets) when interval == screen_width (i'm aware you know it guys) and it looks like making interval and offsets work should make 'automagically' pagingEnabled work as expected.

Will make new issue for UX @kelset as @olegbl will patch not scrolling to last item logic.
@olegbl just to clear things up, and to not do the same stuff, you will not do the UX? Then I could look at it.

@olegbl
Copy link
Contributor

olegbl commented Oct 9, 2018

just to clear things up, and to not do the same stuff, you will not do the UX?

Correct. I spent a long time trying to get scrolling feeling as close to the non-snap version as possible and don't have any ideas for how to make it better.

Quick workaround would be to use smoothScroll

That doesn't really work. smoothScroll always scrolls over the course of 250ms which means that if you're scrolling any further away than about a screen, it feels way too fast.

pagingEnabled is actually special case of interval (offsets) when interval == screen_width

That's only a part of it. The other difference is that pagingEnabled only scrolls one page at a time, which snapToInterval allows you to scroll through multiple snap offsets in one gesture.

P.S. I put up a fix for the snap-to-end issue for Android. It should make it over to GitHub within a couple of weeks.

@chrusart
Copy link
Contributor

chrusart commented Oct 10, 2018

That doesn't really work. smoothScroll always scrolls over the course of 250ms which means that if you're scrolling any further away than about a screen, it feels way too fast.

But this is how it looks like on iOS and it seems it will anyway scroll few items if scrolled fast with interval set. few smaller items feels very ok'ish in 250ms and here I disagree that it doesn't work.
And I was thinking to make workaround to use smoothScroll... only if interval/offsets set, fixed paging w/o interval/offsets set would be used.
Let me check 0.56 again to be sure. Yeah, 0.56 behaves like I described.

That's only a part of it. The other difference is that pagingEnabled only scrolls one page at a time, which snapToInterval allows you to scroll through multiple snap offsets in one gesture.

Well, yes, then it means that pagingEnabled shouldn't be overridden in js and if:

  • no pagingEnabled/interval/offset set - we just scroll normally
  • pagingEnabled w/o interval/offset - we scroll one page (screen width) at a time
  • pagingEnabled w/ interval/offset - then we scroll one item at a time (page here is a width of the item)
  • NO pagingEnabled w/ interval/offset - how much we scroll depends on velocity

otherwise pagingEnabled looses it's meaning if overridden in js w/ interval/offset.
(I hope I wrote it clearly) btw. all my concerns were only about constant speed scrolling with interval/offsets.

Nevertheless fling... and smoothScroll... are actually ending at the same item (i guess), only that fling do it in constant speed, smoothScroll.. takes under consideration initial velocity and do it in 250ms, for few small items it was really good experience.

@alexandrius
Copy link

Can confirm this is fixed in 0.57.2

@chrusart
Copy link
Contributor

@alexandrius Original issue is fixed if this is what you referring to. Probably we should move to new issue:
#21643

@chrusart
Copy link
Contributor

P.S. I put up a fix for the snap-to-end issue for Android. It should make it over to GitHub within a couple of weeks.

Weeks? Well, not scrolling to last item is a major issue here, will try fix it sooner than that.

@olegbl
Copy link
Contributor

olegbl commented Oct 10, 2018

But this is how it looks like on iOS

No, it's not. iOS uses an acceleration curve that's much more similar to Android's fling() than smoothScroll(). It's just a much better algorithm and doesn't suffer from velocity desyncs when changing target position.

I highly recommend you go in, make the change for Android and compare the feel side by side for both long and short lists - smoothScrollTo feels very different from pagingEnabled={false}.

pagingEnabled w/ interval/offset - then we scroll one item at a time (page here is a width of the item)

This was never the behavior on iOS, hence I didn't try to mimic it on Android - though I don't really see any problem with you implementing it.

Nevertheless fling... and smoothScroll... are actually ending at the same item (i guess)

Sort of. Before the changes, the place where the view ended up was completely wrong (it just used velocity as a flat offset in pixels). With the changes, you could easily swap smoothScrollTo() in for fling() and indeed have them end up at the same place.

for few small items it was really good experience.

Yes, and a terrible one for many items. Perhaps there's a threshold somewhere in there where one could switch between the two, not sure.

Weeks? Well, not scrolling to last item is a major issue here, will try fix it sooner than that.

It's just waiting for a review from the RN team. It might happen way faster but I've had to wait weeks in the past, hence the estimate. You can try doing a PR (the fix it trivial - just Math.min(..., maximumOffset) on largerOffset in the snapToInterval part of the algorithm), but I think the same people review those so I doubt it'd be any faster.

@chrusart
Copy link
Contributor

chrusart commented Oct 11, 2018

Well, maybe I should test more on long lists then (more items on screen width) it just feels bad for short ones. @ds8k video shows how it scrolls on small number of items on screen, but it scrolls many items at once, and it is exactly what I'm talking about.

Maybe it doesn't look the same in iOS but it looked more similar before (for short lists at least)

pagingEnabled for scrolling item width I never said it's in iOS, it's just would be if we implement it like this.

@mjmasn
Copy link
Contributor Author

mjmasn commented Oct 11, 2018

@chrusart if you're interested I actually experimented with adding a pagingInterval prop a couple of days ago to control the 'page' size, see https://github.com/mjmasn/react-native/tree/horizontal_scroll_paging_interval (only works on Android, but if anyone wants to finish adding iOS support feel free!). Not sure how likely it would be to be accepted as a PR though...

@chrusart
Copy link
Contributor

Will check that out @mjmasn !

@chrusart
Copy link
Contributor

I've put videos in #21643 how it looked in 0.56.1 on iOS and Android and 0.57.2 in Android to compare.

facebook-github-bot pushed a commit that referenced this issue Oct 11, 2018
Summary:
The end-of-scrollable-range offset was not clipped before the nearestOffset calculation causing the ScrollView to not snap to the end of the view when the width of the ScrollView was not an exact multiple of snapToInterval.

Addresses #21116 (comment)

Reviewed By: yungsters

Differential Revision: D10248545

fbshipit-source-id: 2bdc94ea0a9d9f063769f2c5da4c33d4872b1db2
grabbou pushed a commit that referenced this issue Oct 11, 2018
Summary:
The end-of-scrollable-range offset was not clipped before the nearestOffset calculation causing the ScrollView to not snap to the end of the view when the width of the ScrollView was not an exact multiple of snapToInterval.

Addresses #21116 (comment)

Reviewed By: yungsters

Differential Revision: D10248545

fbshipit-source-id: 2bdc94ea0a9d9f063769f2c5da4c33d4872b1db2
20051231 pushed a commit to 20051231/react-native that referenced this issue Nov 13, 2018
Summary:
ScrollView always clipping children on Android even when `overflow: visible` was specified.
This change just omits the clipping during draw if `overflow: visible` is passed in.
The default is not changed (from hidden to visible) in case there is a performance impact.
Android now matches iOS in behavior. This helps with issue facebook#21116 and resolves facebook#14416.

Reviewed By: shergin

Differential Revision: D9952096

fbshipit-source-id: 367afe33ee7ff0fdc5aa1074d239883aa289888a
sjchmiela pushed a commit to expo/react-native that referenced this issue Dec 15, 2018
Summary:
The snapToOffsets changes improved the flinging algorithm for snapToInterval/snapToOffsets but actually broke it for pagingEnabled because it's meant to only scroll one page at a time.

First, I just brough back the old algorithm, but noticed that it has a bunch of issues (e.g. facebook#20155). So, I tried to improve the algorithm to make sure it uses the proper target offset prediction using the same physics model that Android uses for it's normal scrolling but still be limited to one page scrolls.

This resolves facebook#21116.

Reviewed By: shergin

Differential Revision: D9945017

fbshipit-source-id: be7d4dfd1140f4c4d32bad93a03812dc80286069
@dellwatson
Copy link

dellwatson commented May 23, 2019

the thread is too long, and i didnt get the point how to solve this,

in Android i have to replace FlatList/ ScrollView with ViewPagerAndroid ? since the flatlist in IOS with pagingEnabled is still hard to swipe, while on IOS really easy

@rikur
Copy link

rikur commented May 24, 2019

Yeap there's no momentum when pagingEnabled and I have to concur that the UX on Android is rather horrible.

t-nanava pushed a commit to microsoft/react-native-macos that referenced this issue Jun 17, 2019
Summary:
ScrollView always clipping children on Android even when `overflow: visible` was specified.
This change just omits the clipping during draw if `overflow: visible` is passed in.
The default is not changed (from hidden to visible) in case there is a performance impact.
Android now matches iOS in behavior. This helps with issue facebook#21116 and resolves facebook#14416.

Reviewed By: shergin

Differential Revision: D9952096

fbshipit-source-id: 367afe33ee7ff0fdc5aa1074d239883aa289888a
t-nanava pushed a commit to microsoft/react-native-macos that referenced this issue Jun 17, 2019
Summary:
The snapToOffsets changes improved the flinging algorithm for snapToInterval/snapToOffsets but actually broke it for pagingEnabled because it's meant to only scroll one page at a time.

First, I just brough back the old algorithm, but noticed that it has a bunch of issues (e.g. facebook#20155). So, I tried to improve the algorithm to make sure it uses the proper target offset prediction using the same physics model that Android uses for it's normal scrolling but still be limited to one page scrolls.

This resolves facebook#21116.

Reviewed By: shergin

Differential Revision: D9945017

fbshipit-source-id: be7d4dfd1140f4c4d32bad93a03812dc80286069
t-nanava pushed a commit to microsoft/react-native-macos that referenced this issue Jun 17, 2019
Summary:
The end-of-scrollable-range offset was not clipped before the nearestOffset calculation causing the ScrollView to not snap to the end of the view when the width of the ScrollView was not an exact multiple of snapToInterval.

Addresses facebook#21116 (comment)

Reviewed By: yungsters

Differential Revision: D10248545

fbshipit-source-id: 2bdc94ea0a9d9f063769f2c5da4c33d4872b1db2
@facebook facebook locked as resolved and limited conversation to collaborators Sep 24, 2019
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Sep 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests