Default drag scrolling devices
Summary
#ScrollBehaviors now allow or disallow drag scrolling from specified
PointerDeviceKinds. ScrollBehavior.dragDevices, by default,
allows scrolling widgets to be dragged by all PointerDeviceKinds
except for PointerDeviceKind.mouse.
Context
#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.
Description of change
#This change fixed the unexpected ability to scroll by dragging with a mouse.
If you have relied on the previous behavior in your application, there are several ways to control and configure this feature.
-
Extend
ScrollBehavior,MaterialScrollBehavior, orCupertinoScrollBehaviorto modify the default behavior, overridingScrollBehavior.dragDevices.- With your own
ScrollBehavior, you can apply it app-wide by settingMaterialApp.scrollBehaviororCupertinoApp.scrollBehavior. - Or, if you wish to only apply it to specific widgets, add a
ScrollConfigurationabove the widget in question with your customScrollBehavior.
- With your own
Your scrollable widgets then inherit and reflect this behavior.
- Instead of creating your own
ScrollBehavior, another option for changing the default behavior is to copy the existingScrollBehavior, and set differentdragDevices.- Create a
ScrollConfigurationin your widget tree, and provide a modified copy of the existingScrollBehaviorin the current context usingcopyWith.
- Create a
To accommodate the new configuration of drag devices in ScrollBehavior,
GestureDetector.kind has been deprecated along with
all subclassed instances of the parameter.
A flutter fix is available to migrate existing code
for all gesture detectors from kind to supportedDevices.
The previous parameter kind only allowed one PointerDeviceKind to
be used to filter gestures.
The introduction of supportedDevices makes it possible for more
than one valid PointerDeviceKind.
Migration guide
#Setting a custom ScrollBehavior for your application
#Code before migration:
MaterialApp(
// ...
);Code after migration:
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
// etc.
};
}
// Set ScrollBehavior for an entire application.
MaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
// ...
);Setting a custom ScrollBehavior for a specific widget
#Code before migration:
final ScrollController controller = ScrollController();
ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
);Code after migration:
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');
}
),
);Copy and modify existing ScrollBehavior
#Code before migration:
final ScrollController controller = ScrollController();
ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
);Code after migration:
// ScrollBehavior can be copied and adjusted.
final ScrollController controller = ScrollController();
ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(dragDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
}),
child: ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
),
);Migrate GestureDetectors from kind to supportedDevices
#Code before migration:
VerticalDragGestureRecognizer(
kind: PointerDeviceKind.touch,
);Code after migration:
VerticalDragGestureRecognizer(
supportedDevices: <PointerDeviceKind>{ PointerDeviceKind.touch },
);Timeline
#Landed in version: 2.3.0-12.0.pre
In stable release: 2.5
References
#API documentation:
ScrollConfigurationScrollBehaviorMaterialScrollBehaviorCupertinoScrollBehaviorPointerDeviceKindGestureDetector
Relevant issue:
Relevant PRs:
- Reject mouse drags by default in scrollables
- Deprecate GestureDetector.kind in favor of new supportedDevices
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2024-04-04。 查看文档源码 或者 为本页面内容提出建议.