概述

#

ScrollBehavior 类现在允许或禁止来自指定 PointerDeviceKind 的拖动滚动。默认情况下,ScrollBehavior.dragDevices 允许所有 PointerDeviceKind 拖动滚动组件,除了 PointerDeviceKind.mouse

背景

#

在此更改之前,所有 PointerDeviceKind 都可以拖动 Scrollable 组件。这不符合开发者在使用鼠标输入设备与 Flutter 应用程序交互时的预期。这也使得执行其他鼠标手势变得困难,例如选择包含在 Scrollable 组件中的文本。

现在,继承的 ScrollBehavior 根据 ScrollBehavior.dragDevices 的指定来管理哪些设备可以拖动滚动组件。此 PointerDeviceKind 集合被允许进行拖动。

变更说明

#

此更改修复了通过鼠标拖动进行滚动这一意外行为。

如果您的应用程序依赖于之前的行为,可以通过多种方式控制和配置此功能。

  • 扩展 ScrollBehaviorMaterialScrollBehaviorCupertinoScrollBehavior 以修改默认行为,重写 ScrollBehavior.dragDevices

    • 有了您自己的 ScrollBehavior,您可以通过设置 MaterialApp.scrollBehaviorCupertinoApp.scrollBehavior 将其应用于整个应用程序。
    • 或者,如果您只想将其应用于特定组件,请在相关组件上方添加一个 ScrollConfiguration,并使用您的自定义 ScrollBehavior

您的可滚动组件将继承并反映此行为。

  • 除了创建自己的 ScrollBehavior 之外,改变默认行为的另一个选项是复制现有的 ScrollBehavior,并设置不同的 dragDevices
    • 在您的组件树中创建一个 ScrollConfiguration,并使用 copyWith 提供当前上下文中现有 ScrollBehavior 的修改副本。

为了适应 ScrollBehavior 中拖动设备的新配置,GestureDetector.kind 参数及其所有子类实例已被弃用。提供了一个 flutter fix,用于将所有手势检测器的现有代码从 kind 迁移到 supportedDevices。之前的 kind 参数只允许一个 PointerDeviceKind 用于过滤手势。supportedDevices 的引入使得可以使用多个有效的 PointerDeviceKind

迁移指南

#

为应用程序设置自定义 ScrollBehavior

#

迁移前的代码

Dart
MaterialApp(
  // ...
);

迁移后的代码

Dart
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(),
  // ...
);

为特定组件设置自定义 ScrollBehavior

#

迁移前的代码

Dart
final ScrollController controller = ScrollController();
ListView.builder(
  controller: controller,
  itemBuilder: (BuildContext context, int index) {
   return Text('Item $index');
 }
);

迁移后的代码

Dart
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');
    }
  ),
);

复制并修改现有 ScrollBehavior

#

迁移前的代码

Dart
final ScrollController controller = ScrollController();
ListView.builder(
  controller: controller,
  itemBuilder: (BuildContext context, int index) {
   return Text('Item $index');
 }
);

迁移后的代码

Dart
// 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');
    }
  ),
);

GestureDetectorkind 迁移到 supportedDevices

#

迁移前的代码

Dart
VerticalDragGestureRecognizer(
  kind: PointerDeviceKind.touch,
);

迁移后的代码

Dart
VerticalDragGestureRecognizer(
  supportedDevices: <PointerDeviceKind>{ PointerDeviceKind.touch },
);

时间线

#

引入版本: 2.3.0-12.0.pre
稳定版本:2.5

参考资料

#

API 文档

相关议题

相关 PR