You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何从PhysicalKeyboardKey实例获取合理的按键标签?

如何将PhysicalKeyboardKey转换为LogicalKeyboardKey以获取可用的键标签

你完全可以通过Flutter提供的HardwareKeyboard.instance.mapPhysicalKeyToLogicalKey()方法,将PhysicalKeyboardKey实例转换为对应的LogicalKeyboardKey,从而在发布模式下也能使用keyLabel属性,而且不需要给KeyboardShortcut新增任何属性。

修改后的核心代码部分

在你构建ListTile的位置,替换原来获取debugName的逻辑:

final shortcut = shortcuts[index - 1];
// 将物理键映射为逻辑键
final logicalKey = HardwareKeyboard.instance.mapPhysicalKeyToLogicalKey(shortcut.key);
// 使用逻辑键的keyLabel,兼容发布模式
final keyLabel = logicalKey.keyLabel ?? 'Unknown Key';
return ListTile(
  title: Text(keyLabel),
  subtitle: Text(shortcut.description),
  onTap: shortcut.invoke,
);

完整修改后的MyHomePage代码

class MyHomePage extends StatelessWidget {
  /// Create an instance.
  const MyHomePage({
    super.key,
  });

  /// Build the widget.
  @override
  Widget build(final BuildContext context) {
    final shortcuts = <KeyboardShortcut>[
      KeyboardShortcut(
        description: 'Action 1',
        key: PhysicalKeyboardKey.digit1,
        invoke: () {
          print('Action 1.');
        },
      ),
      KeyboardShortcut(
        description: 'Action 2',
        key: PhysicalKeyboardKey.digit2,
        invoke: () {
          print('Action 2.');
        },
      ),
    ];
    final keyboard = HardwareKeyboard.instance;
    return Scaffold(
      appBar: AppBar(
        title: const Text('Keyboard Shortcuts'),
      ),
      body: ListView.builder(
        itemBuilder: (final listViewContext, final index) {
          if (index == 0) {
            return Focus(
              onKeyEvent: (final node, final event) {
                if (event is KeyRepeatEvent) {
                  return KeyEventResult.ignored;
                }
                for (final shortcut in shortcuts) {
                  if (shortcut.key == event.physicalKey &&
                      shortcut.controlKey == keyboard.isControlPressed &&
                      shortcut.altKey == keyboard.isAltPressed &&
                      shortcut.shiftKey == keyboard.isShiftPressed) {
                    if (event is KeyDownEvent) {
                      shortcut.invoke();
                    }
                    return KeyEventResult.handled;
                  }
                }
                return KeyEventResult.ignored;
              },
              autofocus: true,
              child: const ListTile(
                title: Text('Keyboard area'),
              ),
            );
          }
          final shortcut = shortcuts[index - 1];
          final logicalKey = HardwareKeyboard.instance.mapPhysicalKeyToLogicalKey(shortcut.key);
          final keyLabel = logicalKey.keyLabel ?? 'Unknown Key';
          return ListTile(
            title: Text(keyLabel),
            subtitle: Text(shortcut.description),
            onTap: shortcut.invoke,
          );
        },
        itemCount: shortcuts.length + 1,
        shrinkWrap: true,
      ),
    );
  }
}

关键说明

  • mapPhysicalKeyToLogicalKey()方法会根据当前系统的键盘布局,将物理键映射为对应的逻辑键,这个映射是Flutter内部维护的,无需额外配置。
  • LogicalKeyboardKey.keyLabel属性在发布模式下完全可用,会返回用户能识别的键名称(比如数字键返回"1"、"2",字母键返回"A"、"B"等)。
  • 增加?? 'Unknown Key'的空判断是为了处理极少数可能无法映射的物理键,避免UI出现空内容。

这样就能满足你的需求:不用修改KeyboardShortcut类,同时在发布模式下也能正常显示快捷键的键标签。

内容的提问来源于stack exchange,提问作者Chris Norman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:54:57