在桌面端的开发中,键盘快捷键是非常常见而必要的,比方 Ctrl + F 搜索, Ctrl + C 仿制等。Flutter 既然能够开发桌面端应用,那必然要供给自定义快捷键,触发事情的功用支撑。这便是本节要介绍的 Shortcuts 组件体系,相关代码后续会放入 FlutterUnit 中,敬请重视 ~


1. Shortcuts 组件的简略运用

首要,来个简略的功用体验一下。仍是那初始的计数器项目来开刀,之前是点击按钮数字增加,现在试一下经过快捷键触发更新的逻辑:

Flutter 桌面开发 | 键盘快捷键功能 - Shortcuts 组件

快捷键体系中,Shortcuts 组件保护快捷键(ShortcutActivator)和目的(Intent) 数据的映射,也便是说一个 Shortcuts 组件内部能够定义若干个快捷键。比方下面定义 Ctrl + Q 的快捷键,其对应的目的是 IncrementIntent

Widget buildShortcuts({required Widget child}) {
  return Shortcuts(
    shortcuts: <ShortcutActivator, Intent>{
      LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyQ): const IncrementIntent(),
    },
    child: Actions(
      actions: <Type, Action<Intent>>{
        IncrementIntent:  CallbackAction<IncrementIntent>(onInvoke: _incrementCounter),
      },
      child: Focus(
        autofocus: true,
        child: child,
      ),
    ),
  );
}

我们需求派生 Intent 来自定义需求的目的,作为事情呼应的标识。经过 Actions 组件根据目的来呼应快捷键,其间经过 actions 参数保护类型和 Action 回调事情,触发状况类中 _incrementCounter 办法即可。

另外,快捷键体系需求焦点的支撑,所以需求 Focus 组件,只要焦点在激活状况,快捷键才能够呼应,经过焦点能够操控快捷键是否呼应。想要默认情况下呼应,能够将 autofocus 置为 true 。

---->[状况类中]----
void _incrementCounter(IncrementIntent intent) {
  setState(() {
    _counter++;
  });
}
class IncrementIntent extends Intent { 
    const IncrementIntent(); 
 }

在事情呼应时,能够获取目的目标。所以能够在目的派生类中供给成员数据,以便在事情呼应时进行访问。比方这儿 IncrementIntent 能够有一个增加值的成员,这样在 _incrementCounter 能够获取到目的目标,处理每次自增多少的逻辑。


最后,运用 buildShortcuts 办法包裹在想要呼应快捷键的组件上即可,当然你能够直接套上去,或许封装一个组件单独保护快捷键的处理。这属于代码结构的问题,能够自己斟酌。

Flutter 桌面开发 | 键盘快捷键功能 - Shortcuts 组件


2. 快捷键与焦点的相关

下面实现一些输入框经过 Ctrl + Enter 快捷键发送的功用,介绍一下快捷键和焦点的相关。现在的目的是只要当输入框获取焦点之后,才能够呼应快捷键。对于输入框来说,它内部有 Focus 组件,并且能够供给 FocusNode 焦点目标来操控焦点:对于输入框来说,焦点激活便是可输入状况:

final FocusNode _inputNode = FocusNode();

Flutter 桌面开发 | 键盘快捷键功能 - Shortcuts 组件

TextField 组件能够设置 focusNode 参数设置焦点目标,

Flutter 桌面开发 | 键盘快捷键功能 - Shortcuts 组件

如下所示,供给 buildShortcutsSend 办法,运用 Ctrl + enter 触发 SendMessageIntent 目的。快捷键触发时,回调 _sendMessage 办法,其间撤销焦点,清空文字。焦点撤销之后,就无法呼应快捷键了,当点击输入框时,焦点会再次激活,能够呼应快捷键。

 Widget buildShortcutsSend({required Widget child}) {
   return Shortcuts(
     shortcuts: <ShortcutActivator, Intent>{
       LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.enter): const SendMessageIntent(),
     },
     child: Actions(
       actions: <Type, Action<Intent>>{
         SendMessageIntent: CallbackAction<SendMessageIntent>(onInvoke: _sendMessage),
       },
       child: child,
     ),
   );
 }
void _sendMessage(SendMessageIntent intent) {
  print("====_sendMessage:${ctrl.text}===================");
  _inputNode.unfocus();
  ctrl.clear();
}
 class SendMessageIntent extends Intent {
  const SendMessageIntent();
}

到这儿,键盘快捷键的运用就介绍得差不多了,期望能够对你在桌面端的开发有所协助。关于 Focus 体系也是一个比较复杂的东西,今后有时机再详细介绍。那本文就到这了,谢谢观看 ~