Attempt to implement better scrolling for Flutter Web and Desktop. Includes keyboard, MButton and custom mouse wheel scrolling.

Overview

improved_scrolling

pub package

An attempt to implement better scrolling for Flutter Web and Desktop.

Includes keyboard, MButton and custom mouse wheel scrolling.


Getting started


Example




Usage and features

(from the example app)

final controller = ScrollController();

...

ImprovedScrolling(
      scrollController: controller,
      onScroll: (scrollOffset) => debugPrint(
        'Scroll offset: $scrollOffset',
      ),
      onMMBScrollStateChanged: (scrolling) => debugPrint(
        'Is scrolling: $scrolling',
      ),
      onMMBScrollCursorPositionUpdate: (localCursorOffset, scrollActivity) => debugPrint(
            'Cursor position: $localCursorOffset\n'
            'Scroll activity: $scrollActivity',
      ),
      enableMMBScrolling: true,
      enableKeyboardScrolling: true,
      enableCustomMouseWheelScrolling: true,
      mmbScrollConfig: MMBScrollConfig(
        customScrollCursor: useSystemCursor ? null : const DefaultCustomScrollCursor(),
      ),
      keyboardScrollConfig: KeyboardScrollConfig(
        arrowsScrollAmount: 250.0,
        homeScrollDurationBuilder: (currentScrollOffset, minScrollOffset) {
          return const Duration(milliseconds: 100);
        },
        endScrollDurationBuilder: (currentScrollOffset, maxScrollOffset) {
          return const Duration(milliseconds: 2000);
        },
      ),
      customMouseWheelScrollConfig: const CustomMouseWheelScrollConfig(
        scrollAmountMultiplier: 2.0,
      ),
      child: ScrollConfiguration(
        behavior: const CustomScrollBehaviour(),
        child: GridView(
          controller: controller,
          physics: const NeverScrollableScrollPhysics(),
          scrollDirection: axis,
          padding: const EdgeInsets.all(24.0),
          gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 400.0,
            mainAxisExtent: 400.0,
          ),
          children: buildScrollableItemList(axis),
        ),
      ),
    );

Requirements

  • The ImprovedScrolling Widget must be added as a parent of your scrollable Widget (List/Grid/SingleChildScrollView/etc).
  • You must create and provide the same scroll controller to both the ImprovedScrolling Widget and your scrollable Widget.
  • Optional: If you want to programatically scroll when rotating the mouse wheel and not let the framework manage the scrolling, you can set physics: NeverScrollableScrollPhysics() to your scrollable and then set enableCustomMouseWheelScrolling: true on ImprovedScrolling to enable this feature.

Features:

  • Scrolling using the keyboard (Arrows, Page{Up, Down}, Spacebar, Home, End)

    You need to set enableKeyboardScrolling: true and then you can configure the scrolling amount, duration and curve by using keyboardScrollConfig: KeyboardScrollConfig(...)

  • Scrolling using the middle mouse button ("auto-scrolling")

    You need to set enableMMBScrolling: true and then you can configure the scrolling delay, velocity, acceleration and cursor appearance and size by using mmbScrollConfig: MMBScrollConfig(...)

    There is also a DefaultCustomScrollCursor class which is a default custom cursor implementation

  • Programatically scroll using the mouse wheel

    You need to set enableCustomMouseWheelScrolling: true and then you can configure the scrolling speed, duration, curve and throttling time by using customMouseWheelScrollConfig: CustomMouseWheelScrollConfig(...)

  • Horizontal scrolling using Left/Right arrows or Shift + mouse wheel

    Requires enableKeyboardScrolling: true and enableCustomMouseWheelScrolling: true to be set.


Callbacks:

Other than the above features, there are also a few callbacks available on the ImprovedScrolling Widget:


// Triggers whenever the ScrollController scrolls, no matter how or why
onScroll: (double scrollOffset) => debugPrint(
  'Scroll offset: $scrollOffset',
),

// Triggers whenever the middle mouse button scrolling feature is activated or deactivated
onMMBScrollStateChanged: (bool scrolling) => debugPrint(
  'Is scrolling: $scrolling',
),

// Triggers whenever the cursor is moved on the scrollable area, while the
// middle mouse button feature is active and is scrolling
//
// We also get the current scroll activity (idle or moving up/down/left/right)
// at the time the cursor moves
onMMBScrollCursorPositionUpdate: (
  Offset localCursorOffset,
  MMBScrollCursorActivity scrollActivity,
) => debugPrint(
    'Cursor position: $localCursorOffset\n'
    'Scroll activity: $scrollActivity',
 ),

License

MIT

You might also like...

Flutter plugin for Flutter desktop(macOS/Linux/Windows) to change window size.

desktop_window Flutter plugin for Flutter desktop(macOS/Linux/Windows) to change window size. Usage import 'package:desktop_window/desktop_window.dart

Dec 2, 2022

(Complete flutter application) Exam and training app as social media, prepared with Firebase backend services, Bloc State management, Singleton design pattern, Unit and widget tests, firebase mocking, Custom local libraries, etc.

(Complete flutter application) Exam and training app as social media, prepared with Firebase backend services, Bloc State management, Singleton design pattern, Unit and widget tests, firebase mocking, Custom local libraries, etc.

(Complete flutter application) Exam and training app as social media, prepared with Firebase backend services, Bloc State management, Singleton design pattern, Unit and widget tests, firebase mocking, Custom local libraries, etc.

Jul 14, 2022

Flutter demo application for Apple TV (tvos) using custom Flutter engine

Flutter demo application for Apple TV (tvos) using custom Flutter engine

Flutter for Apple TV A modification of the Flutter engine + test application to demonstrate that Flutter applications run on Apple TV This project (an

Dec 30, 2022

A minimalist Flutter framework for rapidly building custom designs.

A minimalist Flutter framework for rapidly building custom designs.

Show some ❤️ and star the repo. VelocityX is a 100% free Flutter open-source minimalist UI Framework built with Flutter SDK to make Flutter developmen

Jan 8, 2023

Flutter mobile and Web UI

Facebook UI A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if t

Nov 4, 2021

Live portfolio designed using Flutter 2.0 available for android and web.

Live portfolio designed using Flutter 2.0 available for android and web.

DevFolio - Portfolio for Developers Designed live portfolio using Flutter 2.0. Available for Android and Web. 💻 How to install? Before these steps ma

Jan 7, 2023

A simple but powerful path-based navigation router with full web-browser and deeplink support.

nav_stack A simple but powerful path-based routing system, based on MaterialApp.router (Nav 2.0). It has browser / deeplink support and maintains a hi

Nov 28, 2022

A simple but powerful path-based navigation router with full web-browser and deeplink support.

nav_stack A simple but powerful path-based routing system, based on MaterialApp.router (Nav 2.0). It has browser / deeplink support and maintains a hi

Nov 28, 2022

Spyxpo Web to App Builder - a tool which is used to convert a website into an app for iOS, Android, Windows, macOS and Linux.

Spyxpo Web to App Builder - a tool which is used to convert a website into an app for iOS, Android, Windows, macOS and Linux.

Spyxpo Web to App Builder Convert any website into an iOS/Android app. This is a preview build for testing purposes major update coming soon. Supporte

Aug 24, 2022
Comments
  • Horizontal scroll does not work properly (Keyboard)

    Horizontal scroll does not work properly (Keyboard)

    Thanks for you great job.

    We can achieve horizontal scroll by long pressing "Shift" while scroll mouse. But it seems "Shift" only work on the first scrolling. Long pressing does not work.

    https://github.com/rustdesk/rustdesk/issues/1664

    opened by rustdesk 1
  • Show error when we have scroll in both direction in flutter web

    Show error when we have scroll in both direction in flutter web

    When I used the package in flutter web, I got this error in console. I see no issue in result.

    ══╡ EXCEPTION CAUGHT BY ANIMATION LIBRARY ╞═════════════════════════════════════════════════════════
    The following assertion was thrown while notifying status listeners for AnimationController:
    The provided ScrollController is currently attached to more than one ScrollPosition.
    The Scrollbar requires a single ScrollPosition in order to be painted.
    When the scrollbar is interactive, the associated Scrollable widgets must have unique
    ScrollControllers. The provided ScrollController must be unique to a Scrollable widget.
    When the exception was thrown, this was the stack:
    C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49      throw_
    packages/flutter/src/widgets/scrollbar.dart 1508:9                                                                             <fn>
    packages/flutter/src/widgets/scrollbar.dart 1531:14                                                                            [_debugCheckHasValidScrollPosition]
    packages/flutter/src/widgets/scrollbar.dart 1445:14                                                                            [_validateInteractions]
    packages/flutter/src/animation/listener_helpers.dart 233:27                                                                    notifyStatusListeners
    packages/flutter/src/animation/animation_controller.dart 815:7                                                                 [_checkStatusChanged]
    packages/flutter/src/animation/animation_controller.dart 749:5                                                                 [_startSimulation]
    packages/flutter/src/animation/animation_controller.dart 612:12                                                                [_animateToInternal]
    packages/flutter/src/animation/animation_controller.dart 461:12                                                                forward
    packages/flutter/src/widgets/scrollbar.dart 1821:46                                                                            [_handleScrollNotification]
    packages/flutter/src/widgets/notification_listener.dart 130:22                                                                 onNotification
    packages/flutter/src/widgets/framework.dart 3078:18                                                                            dispatchNotification
    packages/flutter/src/widgets/framework.dart 3081:13                                                                            dispatchNotification
    packages/flutter/src/widgets/framework.dart 4375:24                                                                            dispatchNotification
    packages/flutter/src/widgets/notification_listener.dart 60:13                                                                  dispatch
    packages/flutter/src/widgets/scroll_activity.dart 94:90                                                                        dispatchScrollUpdateNotification
    packages/flutter/src/widgets/scroll_position.dart 900:5                                                                        didUpdateScrollPositionBy
    packages/flutter/src/widgets/scroll_position_with_single_context.dart 224:7                                                    pointerScroll
    packages/flutter/src/widgets/scrollable.dart 722:16                                                                            [_handlePointerScroll]
    packages/flutter/src/gestures/pointer_signal_resolver.dart 88:7                                                                resolve
    packages/flutter/src/gestures/binding.dart 451:29                                                                              handleEvent
    packages/flutter/src/gestures/binding.dart 425:14                                                                              dispatchEvent
    packages/flutter/src/rendering/binding.dart 329:11                                                                             dispatchEvent
    packages/flutter/src/gestures/binding.dart 380:7                                                                               [_handlePointerEventImmediately]
    packages/flutter/src/gestures/binding.dart 344:5                                                                               handlePointerEvent
    packages/flutter/src/gestures/binding.dart 302:7                                                                               [_flushPointerEventQueue]
    packages/flutter/src/gestures/binding.dart 285:32                                                                              [_handlePointerDataPacket]
    C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 1105:13               invoke1
    C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 185:5                 invokeOnPointerDataPacket
    C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 130:39                    [_onPointerData]
    C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 295:14                    [_handleWheelEvent]
    C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 559:7                     <fn>
    C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 284:84                    <fn>
    C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 334:14  _checkAndCall
    C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 339:39  dcall
    The AnimationController notifying status listeners was:
      AnimationController#a8507(▶ 0.000)
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    2
    Another exception was thrown: The provided ScrollController is currently attached to more than one ScrollPosition.
    
    opened by P-B1101 1
  • feat: add trackpad support and optimizations

    feat: add trackpad support and optimizations

    This PR brings:

    • fix: scroll becomes slow when scroll quickly (scroll multiple times in seconds).
    • feat: add trackpad support. currently trackpad not working when use custom scroll.

    BREAKING CHANGES:

    since flutter have upgraded to 3.3, which moves events for trackpad from emulated gesture event to its own scroll event. This new logic to fits the latest version of flutter stable, and provided a fix to support trackpad on flutter 3.3+.

    After merge this, flutter which version <3.3 cannot successfully compile this pub because it uses the latest interfaces added by flutter 3.3.

    opened by Kingtous 0
Owner
Adrian Flutur
Adrian Flutur
💙 A simple Flutter app sample with hooks_riverpod, includes HTTP requests by dio using GitHub APIs.

?? A simple Flutter app sample with hooks_riverpod, includes HTTP requests by dio using GitHub APIs.

Kosuke Saigusa 16 Oct 13, 2022
a better implementation of myfatoorah_flutter

myfatoorah_flutter In order to simplify the integration of your application with MyFatoorah payment platforms, we have developed a cutting-edge plugin

Bdaya Development 0 Nov 2, 2021
Try to clone satria, with same feature but better ui

satria A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this i

Gesya Gayatree Solih 9 Nov 8, 2021
A platform adaptive Flutter app for desktop, mobile and web.

Flutter Folio A demo app showcasing how Flutter can deliver a great multi-platform experience, targeting iOS, Android, MacOS, Windows, Linux, and web.

gskinner team 3.5k Dec 28, 2022
Web + mobile + desktop

SwiggyUI SwiggyUI App is a UI clone of a famous food ordering app called Swiggy built using Flutter. Show some ❤️ and star ⭐ the repo if you liked it,

Rudresh 28 Dec 25, 2022
An example showing how to handle common scrolling gesture conflicts in Flutter.

scroll_master An example showing how to handle common scrolling gesture conflicts in Flutter.

null 11 Nov 11, 2022
A Flutter application to demonstrate how to implement Google maps and its advanced options in a flutter app.

google_maps_flutter_example A new Flutter application to demonstrate how to implement flutter google maps in a flutter application and perfoem advance

Hesham Erfan 11.7k Jan 8, 2023
Flutter Package to implement Feedback System in your @Flutter project. Taking Feedback from users made Easy!

Flutter App Feedback Taking feedback from the user made easy! Simply integrate flutter_app_feedback package into your Flutter project and you are read

Mihir Paldhikar 2 Nov 16, 2021
Beautiful Nike Web Design Concept With Flutter Beautiful Nike Web Design Concept With Flutter

flutter_web_nike A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started

Pawan Kumar 23 Jan 28, 2022
Mobile and Desktop whatsapp clone with Flutter UI tool kit

Mobile and Desktop whatsapp clone with Flutter UI tool kit

Travis Okonicha 10 Oct 25, 2022