跳至主要内容

将 ShortcutActivator 和 ShortcutManager 迁移到 KeyEvent 系统

摘要

#

一段时间以来(几年),Flutter 实现了两个关键事件系统。新系统与旧的特定于平台的原始键事件系统达到同等水平,并且原始系统将被移除。为了为此做好准备,正在修改使用旧系统的 Flutter API,并且对于其中的一些 API,我们已决定对 API 进行重大更改,以保持 API 的质量。

上下文

#

在原始的按键事件子系统中,框架和客户端应用程序处理每个平台的差异导致代码过于复杂,并且旧系统无法正确表示系统上按键事件的真实状态。

因此,新的基于KeyEvent的系统诞生了,为了最大程度地减少破坏性更改,它与旧系统并行实现,并打算最终弃用原始系统。这个时间正在快速到来,为了做好准备,我们进行了一些最小的破坏性更改,以保持 API 的质量。

更改说明

#

受影响的 API 摘要

  • ShortcutActivator.accepts 现在接收 KeyEventHardwareKeyboard 作为参数。
  • ShortcutActivator.isActivatedBy 现已弃用。只需改用 accepts 即可。
  • ShortcutActivator.triggers 现在是可选的,如果未实现则返回 null。
  • ShortcutManager.handleKeypress 现在接收 KeyEvent 作为参数。

此更改修改了 ShortcutActivator.accepts 方法,使其接收 KeyEventHardwareKeyboard 作为参数,而不是之前的 RawKeyEventRawKeyboard

ShortcutActivator.accepts 的含义略有改变。在更改之前,假设只有在 ShortcutActivator.triggers 返回 null 或发送到 accepts 的按键事件具有 triggers 列表中的逻辑键时才会调用 accepts。现在,它始终会被调用,并且可以使用 triggers 列表作为性能改进,但不是必需的。Flutter 的子类(例如 SingleActivatorCharacterActivator)已经这样做了。

此更改还修改了 ShortcutManager.handleKeypress 方法,使其接收 KeyEvent 而不是 RawKeyEvent 作为参数。

迁移指南

#

Flutter 框架提供的 API 已经迁移。仅当您使用上一节中列出的任何方法时,才需要进行迁移。

迁移使用 ShortcutActivator 或其子类的 API。

#

KeyEvent 而不是 RawKeyEvent 传递给 ShortcutActivator.accepts。这可能意味着切换获取按键事件的位置。根据获取事件的位置,这可能意味着切换到使用 Focus.onKeyEvent 而不是 Focus.onKey,或者如果使用 FocusScopeFocusNodeFocusScopeNode,则进行类似的更改。

如果您使用的是 RawKeyboardListener,请切换到使用 KeyboardListener。如果您直接访问 RawKeyboard,请改用 HardwareKeyboard。您会发现所有按键事件源都有非原始等效项。

迁移扩展 ShortcutActivator 的 API

#

ShortcutActivator.accepts 方法已修改为接收 KeyEventHardwareKeyboard 而不是 RawKeyEventRawKeyboard 作为参数。

之前

dart
class MyActivator extends ShortcutActivator {
  @override
  bool accepts(RawKeyEvent event, RawKeyboard state) {
    // ... (your implementation here)
    returns false;
  }
  // ...
}

之后

dart
class MyActivator extends ShortcutActivator {
  @override
  bool accepts(KeyEvent event, HardwareKeyboard state) {
    // ... (your implementation here)
    returns false;
  }
  // ...
}

迁移扩展 ShortcutManager 的 API

#

ShortcutManager 类已修改为在 handleKeypress 中接收 KeyEvent 而不是 RawKeyEvent。这两个 API 之间的区别之一是重复键的确定方式不同。在 RawKeyEvent 的情况下,repeat 成员指示重复,但在 RawKeyEvent 代码中,事件类型不同(KeyRepeatEvent)。

之前

dart
class _MyShortcutManager extends ShortcutManager {
  @override
  KeyEventResult handleKeypress(BuildContext context, RawKeyEvent event) {
    if (event is! RawKeyDownEvent) {
      return KeyEventResult.ignored;
    }
    if (event.repeat) {
      // (Do something with repeated keys.)
    }
    // ... (your implementation here)
    return KeyEventResult.handled;
  }
}

之后

dart
class _MyShortcutManager extends ShortcutManager {
  @override
  KeyEventResult handleKeypress(BuildContext context, KeyEvent event) {
    if (event is! KeyDownEvent && event is! KeyRepeatEvent) {
      return KeyEventResult.ignored;
    }
    if (event is KeyRepeatEvent) {
      // (Do something with repeated keys.)
    }
    // ... (your implementation here)
    return KeyEventResult.handled;
  }
}

时间线

#

包含于版本:3.17.0-5.0.pre
稳定版发布:3.19.0

参考

#

API 文档

相关问题

相关 PR