将 ShortcutActivator 和 ShortcutManager 迁移到 KeyEvent 系统
概述
#一段时间以来(多年),Flutter 已经实现了两个关键事件系统。新系统已与旧的平台特定原始按键事件系统达到同等水平,而旧的原始系统将被移除。为了做好准备,Flutter 中使用旧系统的 API 正在被修改,对于其中少数 API,我们已决定进行 API 的破坏性更改,以维护 API 的质量。
背景
#在原始按键事件子系统中,处理框架和客户端应用程序中的每个平台的怪癖导致代码过于复杂,而旧系统未能正确表示系统中按键事件的真实状态。
因此,新的 KeyEvent
基于的系统应运而生,为了最大限度地减少破坏性更改,它与旧系统并行实现,目的是最终弃用原始系统。现在这一时刻即将来临,为了做好准备,我们进行了一些必要的最小破坏性更改,以维护 API 的质量。
变更说明
#受影响的 API 摘要
ShortcutActivator.accepts
现在接收KeyEvent
和HardwareKeyboard
。ShortcutActivator.isActivatedBy
已被弃用。只需调用accepts
即可。ShortcutActivator.triggers
现在是可选的,如果未实现则返回 null。ShortcutManager.handleKeypress
现在接收KeyEvent
。
此更改将 ShortcutActivator.accepts
方法修改为接收 KeyEvent
和 HardwareKeyboard
,而不是之前的 RawKeyEvent
和 RawKeyboard
。
ShortcutActivator.accepts
的含义已略有改变。在更改之前,假定 accepts
仅在 ShortcutActivator.triggers
返回 null 时调用,或者发送到 accepts
的按键事件的逻辑键存在于 triggers
列表中时调用。现在它总是被调用,并且可能将 triggers
列表用作性能改进,但不是必需的。Flutter 子类,如 SingleActivator
和 CharacterActivator
,已经这样做了。
此更改还将 ShortcutManager.handleKeypress
方法修改为接收 KeyEvent
而不是 RawKeyEvent
。
迁移指南
#Flutter 框架提供的 API 已迁移。仅当您使用上一节中列出的任何方法时,才需要迁移。
迁移使用 ShortcutActivator
或其子类的 API。
#将 KeyEvent
传递给 ShortcutActivator.accepts
,而不是 RawKeyEvent
。这可能意味着需要更改获取按键事件的来源。根据您的获取方式,这可能意味着切换到使用 Focus.onKeyEvent
而不是 Focus.onKey
,或者如果您使用 FocusScope
、FocusNode
或 FocusScopeNode
,则进行类似的更改。
如果您正在使用 RawKeyboardListener
,请切换到使用 KeyboardListener
。如果您直接访问 RawKeyboard
,请使用 HardwareKeyboard
。您会发现所有按键事件源都有非原始的等效项。
迁移扩展 ShortcutActivator
的 API
#ShortcutActivator.accepts
方法已修改为接收 KeyEvent
和 HardwareKeyboard
,而不是 RawKeyEvent
和 RawKeyboard
。
之前
class MyActivator extends ShortcutActivator {
@override
bool accepts(RawKeyEvent event, RawKeyboard state) {
// ... (your implementation here)
returns false;
}
// ...
}
之后
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
)。
之前
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;
}
}
之后
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