概述

#

一段时间以来(数年),Flutter 已经实现了两个按键事件系统。新系统已与旧的特定于平台的原始按键事件系统达到同等水平,旧的原始系统将被移除。为此,使用旧系统的 Flutter 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。您会发现所有按键事件源都有非原始(non-raw)的等效项。

迁移扩展 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