Flutter Web: Cannot scroll with mouse down (drag) (Flutter 2.5+)
Asked Answered
N

5

34

[Update]

I can confirm this issue happened in flutter above 2.5. Using 2.2.3 is fine. The question becomes why this feature been removed in 2.5 ? And how to enable it in flutter 2.5?

[Origin Question]

I'm using SingleChildScrollView on flutter web with desktop browser. Scrolling only works on mouse wheel but not on mouse click (drag). How can I map mouse click to touch and scroll like mobile?

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SingleChildScrollView(
        child: Column(
          children: List<Widget>.generate(50, (i) => Text(i.toString())).toList(),
        ),
      ),
    );
  }
}
flutter doctor -v
[✓] Flutter (Channel master, 2.6.0-6.0.pre.6, on Ubuntu 20.04.3 LTS 5.11.0-34-generic, locale en_US.UTF-8)
    • Flutter version 2.6.0-6.0.pre.6 at /home/XXX
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 0c5431d99c (12 days ago), 2021-09-05 22:31:02 -0400
    • Engine revision b9c633900e
    • Dart version 2.15.0 (build 2.15.0-82.0.dev)

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Ubuntu 20.04.3 LTS 5.11.0-34-generic
    • Chrome (web)    • chrome • web-javascript • Google Chrome 93.0.4577.82
Nick answered 18/9, 2021 at 8:1 Comment(7)
what the error you found?Grume
no errors. just can't scroll by mouse dragNick
but in my machine, it works perfectlyGrume
you use master version, try to use stable version I hope it will work for you.Grume
Debug your app and then find what errors are executing when you are trying to scroll downRutledge
try MaterialApp( scrollBehavior: MaterialScrollBehavior().copyWith( dragDevices: {PointerDeviceKind.mouse}, ),Ng
It's not an issue.. it is intentionalAstor
N
36

Flutter change mouse scroll behavior after 2.5. See this for detail.

class MyCustomScrollBehavior extends MaterialScrollBehavior {
  // Override behavior methods and getters like dragDevices
  @override
  Set<PointerDeviceKind> get dragDevices => { 
    PointerDeviceKind.touch,
    PointerDeviceKind.mouse,
    // etc.
  };
}

// ScrollBehavior can be set for a specific widget.
final ScrollController controller = ScrollController();
ScrollConfiguration(
  behavior: MyCustomScrollBehavior(),
  child: ListView.builder(
    controller: controller,
    itemBuilder: (BuildContext context, int index) {
     return Text('Item $index');
    }
  ),
);
Nick answered 18/9, 2021 at 12:19 Comment(1)
how to integration test this? Tried following link but scroll seems to be not happening #64406714Kim
R
77

My final solution was a combination of the suggestions, wanting drag scrolling everywhere, so used this:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      scrollBehavior: MaterialScrollBehavior().copyWith(
        dragDevices: {PointerDeviceKind.mouse, PointerDeviceKind.touch, PointerDeviceKind.stylus, PointerDeviceKind.unknown},
      ),
      ...

Simple enough...

Rite answered 19/1, 2022 at 9:57 Comment(0)
N
36

Flutter change mouse scroll behavior after 2.5. See this for detail.

class MyCustomScrollBehavior extends MaterialScrollBehavior {
  // Override behavior methods and getters like dragDevices
  @override
  Set<PointerDeviceKind> get dragDevices => { 
    PointerDeviceKind.touch,
    PointerDeviceKind.mouse,
    // etc.
  };
}

// ScrollBehavior can be set for a specific widget.
final ScrollController controller = ScrollController();
ScrollConfiguration(
  behavior: MyCustomScrollBehavior(),
  child: ListView.builder(
    controller: controller,
    itemBuilder: (BuildContext context, int index) {
     return Text('Item $index');
    }
  ),
);
Nick answered 18/9, 2021 at 12:19 Comment(1)
how to integration test this? Tried following link but scroll seems to be not happening #64406714Kim
O
18

Flutter Web listview don't detect the mouse scroll or drag event. You should add scrollConfiguration than only mouse scroll and touch event will work. First wrap listview with ScrollConfiguration and add behavior. You can see live example here

ScrollConfiguration(
    behavior: ScrollConfiguration.of(context).copyWith(dragDevices: {
      PointerDeviceKind.touch,
      PointerDeviceKind.mouse,
    },),
    child: ListView(
      controller: _controller,
      physics: const AlwaysScrollableScrollPhysics(),
      scrollDirection: Axis.horizontal,
      children: <Widget>[
      
          for (int index = 0; index < showThumbnailList.length; index++) _thumbnail(showThumbnailList[index], index)
       
        // showThumbnailList.map((x) => _thumbnail(x) ).toList()),
      ],
    ),
  ),
Owens answered 30/9, 2021 at 11:35 Comment(0)
S
3

For the web, the code is different. You need to tie the ROW to a LISTVIEW and in turn to m SCROLLCONFIGURATION

Container(
          width: 500,
          height: 200,
          child: ScrollConfiguration(
            behavior: ScrollConfiguration.of(context).copyWith(
              dragDevices: {
                PointerDeviceKind.touch,
                PointerDeviceKind.mouse,
              },
            ),
            child: ListView(
              controller: _controller,
              physics: const AlwaysScrollableScrollPhysics(),
              scrollDirection: Axis.horizontal,
              children: <Widget>[
                                          Container(width: 100, height: 10,color: Colors.red,),
                                          Container(width: 100, height: 10,color: Colors.blue,),
                                          Container(width: 100, height: 10,color: Colors.green,),
                                          Container(width: 100, height: 10,color: Colors.yellow,),
                                          Container(width: 100, height: 10,color: Colors.orange,),
              ],
            ),
          ),
        ),
Sublapsarianism answered 27/9, 2022 at 19:17 Comment(0)
I
0

Try This, I Did It

class scrollHorizontal extends StatefulWidget{
  State<scrollHorizontal> createState() => _windowsScroll();
}

class _windowsScroll extends State<scrollHorizontal>{
  final ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext Context){
    return GestureDetector(
        onHorizontalDragUpdate: (details) {
          // Scroll horizontally when the user drags horizontally (mouse clicks)
          final newScrollOffset = scrollController.offset - (details.delta.dx * 2);
          scrollController.jumpTo(
            newScrollOffset
          );
        },
      child: SingleChildScrollView(
        controller: scrollController,
        scrollDirection: Axis.horizontal,
        child: Row(
          children: [
            // Content Here
          ],
        ),
      ),
    );
  }
}
Incursive answered 31/7, 2023 at 17:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.