跳至主要內容

將 ShortcutActivator 和 ShortcutManager 遷移至 KeyEvent 系統

摘要

#

一段時間以來(數年),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。您會發現所有按鍵事件來源都有非原始的對應項。

遷移擴充 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