Repository navigation
Scrolling with two fingers scrolls twice as fast #11884
Description
Activity
- addedf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.
on Aug 31, 2017 - addedframeworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.
on Sep 1, 2017 While this is awesome, I suspect this will block AX work and we should remove it. :)
The scrolling speed increases with the number of fingers on screen.
Reacted by dasmikko, jbheuschen, Niklas Higi, Vlad Bondarenko, Dimitri, Zhiyuan Hong, Trym Nilsen, Parth Kabra, Yechan Choi, Delthon R. Villanueva and 22 moreReacted by Iskandar Zulqarnain HilmiI still come across with such problem with 1.9.1 +hotfix4 & 5;
any progress on this?Still persists (master v1.16.3-pre.56)
checked with that simple code
import 'package:flutter/material.dart'; void main() => runApp(MaterialApp(home: MyApp(),)); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { return Scaffold( body: ListView( children: List.generate(100, (index) => ListTile( title: Text(index.toString()), )), ), ); } }The scrolling speed increases according to the number of fingers on screen.
- addedhas reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onf: gesturesflutter/packages/flutter/gestures repository.flutter/packages/flutter/gestures repository.
on Mar 27, 2020 Part of: #38926
- addedP2Important issues not at the top of the work listImportant issues not at the top of the work list
on May 29, 2020 Persists with current master
1.21.0-6.0.pre.38flutter doctor -v
[✓] Flutter (Channel master, 1.21.0-6.0.pre.38, on Mac OS X 10.15.6 19G73, locale en-GB) • Flutter version 1.21.0-6.0.pre.38 at /Users/nevercode/dev/flutter • Framework revision 8e0eee9008 (5 hours ago), 2020-07-26 23:38:01 -0700 • Engine revision 626244a72c • Dart version 2.9.0 (build 2.9.0-21.0.dev a3815b6590) • Pub download mirror https://pub.flutter-io.cn • Flutter download mirror https://storage.flutter-io.cn [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3) • Android SDK at /Users/nevercode/Library/Android/sdk • Platform android-29, build-tools 29.0.3 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 11.6) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.6, Build version 11E708 • CocoaPods version 1.9.1 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.0) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin version 47.1.2 • Dart plugin version 193.7361 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) [✓] VS Code (version 1.47.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.12.2 [✓] Connected device (5 available) • Redmi Note 7 (mobile) • 6345c469 • android-arm64 • Android 9 (API 28) • Nevercode’s iPhone (mobile) • b668e524315069f3db3661ac11ff1f66afafebdb • ios • iOS 13.6 • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.6 19G73 • Web Server (web) • web-server • web-javascript • Flutter Tools • Chrome (web) • chrome • web-javascript • Google Chrome 84.0.4147.89 • No issues found!- addedfound in release: 1.21Found to occur in 1.21Found to occur in 1.21
on Jul 27, 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.Reacted by RobenHELS and Souvik Biswas25 remaining items
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:
enum MultiTouchScrollBehavior { platformDefault, average, first, last, sum }
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
Reacted by Foti Dim, Alexandre Lion, melvspace and asaarnakTry 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.
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.
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.
Yes, our goal is to be as close as possible to the "native" behavior to not disrupt a user's muscle memory.
Reacted by Jacob PritchettWow, 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.
- added a commit that references this issue
on Nov 30, 2023 - addedr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version
on Dec 1, 2023 - Reacted by esentis, Justin, Sander in 't Hout, Jacob Pritchett, melvspace, lemteay, fuxianwei, Jan Marsh, Florian Schmitz, xubaolin and 14 moreReacted by Fareez Iqmal, Morgan Hunt, Neeraj, Josip Krnjic, Hari07, Christopher H, Hitik Saini and DQSSReacted by Boolean, Utpal Barman, Jeroen Meijer (at Bloom), Mikel Corcuera, 2³¹-1 and Christopher H
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.Reacted by Tahiru Agbanwa, Jens Becker and NReacted by Tahiru AgbanwaThis 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.- locked as resolved and limited conversation to collaborators
on Dec 23, 2023 - added a commit that references this issue
on Dec 29, 2023 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.

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.