概述

#

ScrollBehavior 現在允許或禁止來自指定 PointerDeviceKind 的拖動滾動。預設情況下,ScrollBehavior.dragDevices 允許透過除 PointerDeviceKind.mouse 之外的所有 PointerDeviceKind 來拖動滾動小部件。

背景

#

在此更改之前,所有 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 提供了一個修復程式,可以將所有手勢檢測器從 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');
    }
  ),
);

GestureDetectors 從 kind 遷移到 supportedDevices

#

遷移前的程式碼

dart
VerticalDragGestureRecognizer(
  kind: PointerDeviceKind.touch,
);

遷移後的程式碼

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

時間線

#

釋出版本:2.3.0-12.0.pre
穩定版本:2.5

參考資料

#

API 文件

相關議題

相關 PR