Repository navigation
Scrolling with two fingers scrolls twice as fast #11884
Copy link
Copy link
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listcustomer: crowdAffects or could affect many people, though not necessarily a specific customer.Affects or could affect many people, though not necessarily a specific customer.f: gesturesflutter/packages/flutter/gestures repository.flutter/packages/flutter/gestures repository.f: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.found in release: 3.7Found to occur in 3.7Found to occur in 3.7found in release: 3.9Found to occur in 3.9Found to occur in 3.9frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework team
Description
When scrolling a Flutter list with two fingers the list scrolls twice as fast.
In native Android or iOS apps, the list continues to scroll in regular speed even with two fingers.
Note: This is NOT specific to accessibility scrolling with two fingers. It's visible even when accessibility is disabled. However, it's also a problem for accessibility scrolling, where using two fingers are commonly used for scrolling.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listcustomer: crowdAffects or could affect many people, though not necessarily a specific customer.Affects or could affect many people, though not necessarily a specific customer.f: gesturesflutter/packages/flutter/gestures repository.flutter/packages/flutter/gestures repository.f: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.found in release: 3.7Found to occur in 3.7Found to occur in 3.7found in release: 3.9Found to occur in 3.9Found to occur in 3.9frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework team
Activity
eseidelGoogle commentedon Sep 1, 2017
While this is awesome, I suspect this will block AX work and we should remove it. :)
tevjef commentedon Sep 22, 2018
The scrolling speed increases with the number of fingers on screen.
wanjm commentedon Oct 18, 2019
I still come across with such problem with 1.9.1 +hotfix4 & 5;
any progress on this?
VladyslavBondarenko commentedon Mar 27, 2020
Still persists (master v1.16.3-pre.56)
checked with that simple code
The scrolling speed increases according to the number of fingers on screen.
dkwingsmt commentedon Mar 27, 2020
Part of: #38926
VladyslavBondarenko commentedon Jul 27, 2020
Persists with current master
1.21.0-6.0.pre.38flutter doctor -v
fzyzcjy commentedon Oct 6, 2020
I find a workaround for it! :D
Please look at this question (answered by myself after digging into flutter source code).
Note: Do not worry about that question's title. If you set
onlyScrollableWhenMultiFinger: trueinside my sample shown there, you will solve this question, without disabling single finger scrolling.25 remaining items
JacobSyndeo commentedon Nov 15, 2023
Touching (ha) on @gnprice's comment regarding scroll behavior, Apple platforms average the motion of all fingers, rather than summing them.Try scrolling with two fingers, then leaving one in place while continuing to move the second. You'll notice the motion is now halved. Now pause the one that you kept moving and moved the first one in the other direction. You'll see it moves back at half speed as well. Now move both fingers towards each other, and then back apart again; you shouldn't see much scroll motion at all.It essentially creates a virtual scroll "touch" at the average/midpoint between the two fingers. And I believe that this implementation that would be a great solution here as well, at least when targeting Apple platforms.EDIT: @goderbauer pointed out that iOS actually uses a different algorithm now, which I'll take a stab at implementing.
As Android's behavior differs, listening only to the most recent touch, I believe Flutter should do the same when targeting Android.
There's definitely something to be said for having consistent behavior across platforms (and this is one of Flutter's strengths), but scrolling feels like such a fundamental part of the UX that I believe it should be tailored to each platform's stock behavior by default.
But in the spirit of full customization, (while this runs counter to good UX IMO), if certain developers really want to set a specific behavior across their app regardless of platform, we can expose this as an enum option.
Something like this:
Where
platformDefaultusesaveragefor Apple platforms andlastfor Android. We could addfirstfor new behavior, but I'm not certain of the value. Finally,sumwould be the current existing behavior.Whether or not we want to leave existing projects on
sumor default them toplatformDefaultmoving forward is another discussion, IMO.Thoughts? I'd be willing to try to build this out for proposal if folks are interested.
EDIT: PR open here: #138763
goderbauer commentedon Nov 20, 2023
I tried this in a number of Apple apps on iOS 17 (e.g. the App Store and the Settings app) and wasn't able to see this behavior.
Yes, our goal is to be as close as possible to the "native" behavior to not disrupt a user's muscle memory.
JacobSyndeo commentedon Nov 20, 2023
Wow, would you look at that… I feel like I'm in the twilight zone or something, because I could've sworn that's how it worked. (Perhaps it worked this way in the past? In any case, let's only focus on what current versions do.)
In any case, I stand corrected; thanks for pointing that out, @goderbauer.
(Unfortunate, too… I was just now opening a PR that included a behavior fix for both iOS and Android, with Android using the last-touch behavior based on @xu-baolin's solution, and iOS using the averaging behavior I thought it had. I'll have to refactor the latter!)
Anyway, at a glance, iOS' actual algorithm appears to be more complicated.
If multiple fingers are onscreen at a time, it'll listen fully to (and thus fully track) whichever one you move:
IMG_2271-480.mov
Also key, of course, is that moving two fingers together tracks the fingers' midpoint, which is essentially the averaging behavior I mentioned earlier. You can confirm this by dragging two fingers along the screen, but having one start moving faster than the other one. However, if one of the two moving fingers stops moving, the system reverts to fully tracking the one that's actively moving.
Essentially, for iOS, it seems like we need to consider moving fingers as "active" participants, and average their position and motion. But when they're no longer moving (perhaps their motion delta per-frame is below a certain threshold), they're to be considered "inactive", and thus exempt from the averaging.
IMG_2273-480.mov
There is, however, a baffling quirk… if at any point a finger is lifted, the remaining fingers seem to sometimes be forcefully rendered "inactive" by iOS, and will be entirely ignored for the remainder of their time in contact with the display. But I don't know that we need to worry about nor replicate this level of nuance, as I'm not sure it's even intentional due to its apparent coin-flip nature. If anyone can see a pattern in this behavior, please let me know. It seems to exist to facilitate "fling" scrolling even if the user accidentally has another finger sitting onscreen, but I'm unsure.
I'll modify my solution in light of this, sans implementing the quirk for now.
Introduce multi-touch drag strategies for `DragGestureRecognizer` (#1…
simonpham commentedon Dec 4, 2023
It's time guys. We can no longer check if an app is written in Flutter using this scrolling behaviour.

squirelboy360 commentedon Dec 8, 2023
UnicornsOnLSD commentedon Dec 8, 2023
Take a look at the PR -
MultiTouchDragBehavior.sumis available if you wanted the old scrolling for some reason. The Flutter docs has an interesting page on how it adapts to the platform if you're interested.squirelboy360 commentedon Dec 8, 2023
esentis commentedon Dec 9, 2023
github-actions commentedon Dec 23, 2023
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.Introduce multi-touch drag strategies for `DragGestureRecognizer` (fl…
gnprice commentedon Jan 4, 2024
For the sake of making the outcome visible explicitly on this thread: the current solution is that the default behavior on all platforms is that the latest finger controls the scrolling. That's the same as the Android native behavior, as described at #11884 (comment).
See #136708 which made the fix, and the docs at:
https://main-api.flutter.dev/flutter/gestures/DragGestureRecognizer/multitouchDragStrategy.html
https://main-api.flutter.dev/flutter/gestures/MultitouchDragStrategy.html
(I figured this was worth clarifying here because the latest discussion above was toward a different option, where we'd also implement the iOS native behavior and make that the default on iOS. That may still happen in the future if there's a desire for it, but it'd be its own issue.)
Very happy this is fixed! Thanks @xu-baolin @JacobSyndeo and everyone else who contributed.