[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
-
what the error you found?Jahidul Islam– Jahidul Islam2021年09月18日 08:06:26 +00:00Commented Sep 18, 2021 at 8:06
-
no errors. just can't scroll by mouse dragJosh Chiu– Josh Chiu2021年09月18日 08:08:53 +00:00Commented Sep 18, 2021 at 8:08
-
but in my machine, it works perfectlyJahidul Islam– Jahidul Islam2021年09月18日 08:10:53 +00:00Commented Sep 18, 2021 at 8:10
-
you use master version, try to use stable version I hope it will work for you.Jahidul Islam– Jahidul Islam2021年09月18日 08:16:03 +00:00Commented Sep 18, 2021 at 8:16
-
Debug your app and then find what errors are executing when you are trying to scroll downKhaby Lame– Khaby Lame2021年09月18日 11:34:53 +00:00Commented Sep 18, 2021 at 11:34
6 Answers 6
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...
1 Comment
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');
}
),
);
1 Comment
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()),
],
),
),
Comments
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,),
],
),
),
),
Comments
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
],
),
),
);
}
}
Comments
You asked for the reason. Here is it is. Summary: For Web developer people, moving from Traditional web framework to Flutter, they found it weird that we can scroll with mouse drag everywhere. Hence, they made it optional.
Prior to this change, all PointerDeviceKinds could drag a Scrollable widget. This did not match developer expectations when interacting with Flutter applications using mouse input devices. This also made it difficult to execute other mouse gestures, like selecting text that was contained in a Scrollable widget.
Now, the inherited ScrollBehavior manages which devices can drag scrolling widgets as specified by ScrollBehavior.dragDevices. This set of PointerDeviceKinds are allowed to drag.
Source: https://docs.flutter.dev/release/breaking-changes/default-scroll-behavior-drag