概述

#

一段时间以来(多年),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 的含义已略有改变。在更改之前,假定 accepts 仅在 ShortcutActivator.triggers 返回 null 时调用,或者发送到 accepts 的按键事件的逻辑键存在于 triggers 列表中时调用。现在它总是被调用,并且可能将 triggers 列表用作性能改进,但不是必需的。Flutter 子类,如 SingleActivatorCharacterActivator,已经这样做了。

此更改还将 ShortcutManager.handleKeypress 方法修改为接收 KeyEvent 而不是 RawKeyEvent

迁移指南

#

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

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

#

KeyEvent 传递给 ShortcutActivator.accepts,而不是 RawKeyEvent。这可能意味着需要更改获取按键事件的来源。根据您的获取方式,这可能意味着切换到使用 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