如何在没有 RawKeyboardListener 的情况下检测颤振中的按键情况

问题描述 投票:0回答:3

我正在尝试检测抖动中的“Enter”、“Delete”和“Backspace”等按键。我使用

RawKeyboardListener
的问题是它会将焦点从任何子小部件上移开。

例如

RawKeyboardListener(
  focusNode: _focusNode,
  onKey: handleKey,
  child: TextField()
)

这使得无法检测两个按键并同时使用

Textfield

有没有人有其他方法来检测按键。

谢谢

flutter dart keyboard-events
3个回答
13
投票

Flutter 有一个键盘服务,可以为 Flutter 提供来自硬件键盘的原始按键事件,您也可以要求该服务为您提供按键事件。

这种方法的一个好处是它不会阻止现有的 Flutter 焦点节点接收事件,因此您不必手动处理键盘事件传播。

您可以像这样向该服务添加侦听器:

import 'package:flutter/services.dart';

ServicesBinding.instance.keyboard.addHandler(_onKey);

...其中

_onKey
bool Function(KeyEvent)
。这是一个事件处理程序示例:

bool _onKey(KeyEvent event) {
  final key = event.logicalKey.keyLabel;

  if (event is KeyDownEvent) {
    print("Key down: $key");
  } else if (event is KeyUpEvent) {
    print("Key up: $key");
  } else if (event is KeyRepeatEvent) {
    print("Key repeat: $key");
  }

  return false;
}

请参阅此处了解更多信息:https://api.flutter.dev/flutter/services/HardwareKeyboard/addHandler.html

请注意,即使文本框当前处于焦点状态,此事件处理程序也将始终接收按键事件。


这是在小部件中使用此技术的示例:

import 'package:flutter/services.dart';

// ...

class MyApp extends StatefulWidget {
  // ...
}

class _MyAppState extends State<MyApp> {
  // ...

  bool _onKey(KeyEvent event) {
    final key = event.logicalKey.keyLabel;

    if (event is KeyDownEvent) {
      print("Key down: $key");
    } else if (event is KeyUpEvent) {
      print("Key up: $key");
    } else if (event is KeyRepeatEvent) {
      print("Key repeat: $key");
    }

    return false;
  }

  @override
  void initState() {
    super.initState();
    ServicesBinding.instance.keyboard.addHandler(_onKey);
  }

  @override
  void dispose() {
    ServicesBinding.instance.keyboard.removeHandler(_onKey);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // ...
  }
}

5
投票

您可以使用 dart_html 中的以下内容:

    window.onKeyPress.listen((KeyboardEvent e) {
      print(e.charCode.toString() + " " + new String.fromCharCode(e.charCode));
    });

3
投票

您可以在有状态小部件中使用

dart:ui
并在
window.onKeyData
中设置方法
initState

请小心使用该方法,就像屏幕上有任何可聚焦节点一样,您也需要将事件传递给它们,否则,例如,TextField 将无法工作。

  @override
  void initState() {
    window.onKeyData = (final keyData) {
      if (keyData.logical == LogicalKeyboardKey.escape.keyId) {
        widget.onPressed();

        return true;
      }

      /// Let event pass to other focuses if it is not the key we looking for
      return false;
    };
    super.initState();
  }

  @override
  void dispose() {
    window.onKeyData = null;
    super.dispose();
  }
© www.soinside.com 2019 - 2024. All rights reserved.