将 ShortcutActivator 和 ShortcutManager 迁移到 KeyEvent 系统
概述
#一段时间以来(数年),Flutter 已经实现了两个按键事件系统。新系统已与旧的特定于平台的原始按键事件系统达到同等水平,旧的原始系统将被移除。为此,使用旧系统的 Flutter 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
的含义略有改变。在更改之前,假定只有当 ShortcutActivator.triggers
返回 null,或者发送到 accepts
的按键事件包含在 triggers
列表中的逻辑键时,才会调用 accepts
。现在它总是被调用,并且可以使用 triggers
列表作为性能改进,但并非必须。Flutter 子类如 SingleActivator
和 CharacterActivator
已经这样做了。
此更改还将 ShortcutManager.handleKeypress
方法修改为接受 KeyEvent
而不是 RawKeyEvent
。
迁移指南
#Flutter 框架提供的 API 已完成迁移。仅当您使用上一节中列出的任何方法时才需要迁移。
迁移使用 ShortcutActivator
或其子类的 API。
#将 KeyEvent
而不是 RawKeyEvent
传递给 ShortcutActivator.accepts
。这可能意味着您需要更改获取按键事件的位置。根据获取方式,这可能意味着切换到使用 Focus.onKeyEvent
而不是 Focus.onKey
,或者在使用 FocusScope
、FocusNode
或 FocusScopeNode
时进行类似更改。
如果您正在使用 RawKeyboardListener
,请改用 KeyboardListener
。如果您直接访问 RawKeyboard
,请改用 HardwareKeyboard
。您会发现所有按键事件源都有非原始(non-raw)的等效项。
迁移扩展 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