Flutter RawKeyboardListener收听了两次? [英] Flutter RawKeyboardListener listening twice?
问题描述
我想要实现的是在查看此小部件时,当 TextField
时, RawKeyboardListener
开始立即收听。未选中/未聚焦。它运行 HandleKey函数
来处理我想使用 keyCode
进行的操作。
What I am trying to achieve is when viewing this widget, the RawKeyboardListener
starts listening straight away when the TextField
is not selected/in focus. It runs the HandleKey function
to deal with what I want to do with the keyCode
.
我遇到的问题是第一次运行应用程序时, handleKey函数
似乎正在运行两次。因此,在下面的示例中,它将打印为什么当我只输入1个键时两次运行两次$ _keyCode
两次。我认为它监听keyUp和keyDown。我想要的结果是它只能运行一次...
The issue I am having is when running the app for the first time, the handleKey function
seems to be running twice. So in the example below it would print why does this run twice $_keyCode
TWICE when I only enter 1 key. I think it listens to keyUp AND keyDown. The result I want is for it to only run once...
但是,当我选择TextField并使用模拟器进行常规提交时,代码也能正常工作键盘。
However, the code works fine as well when I select the TextField and do a regular submit with the emulator keyboard.
我正在努力理解为什么它仅在与TextField交互后才出现问题。我觉得它需要某个地方的未来
或 await
吗?但是我不知道。
I am struggling to understand why it only has a problem after interacting with the TextField. I feel like it needs a Future
or await
somewhere? but I have no idea.
请帮助。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
class KeyboardListener extends StatefulWidget {
KeyboardListener();
@override
_RawKeyboardListenerState createState() => new _RawKeyboardListenerState();
}
class _RawKeyboardListenerState extends State<KeyboardListener> {
TextEditingController _controller = new TextEditingController();
FocusNode _textNode = new FocusNode();
@override
initState() {
super.initState();
}
//Handle when submitting
void _handleSubmitted(String finalinput) {
setState(() {
SystemChannels.textInput.invokeMethod('TextInput.hide'); //hide keyboard again
_controller.clear();
});
}
handleKey(RawKeyEventDataAndroid key) {
String _keyCode;
_keyCode = key.keyCode.toString(); //keycode of key event (66 is return)
print("why does this run twice $_keyCode");
}
_buildTextComposer() {
TextField _textField = new TextField(
controller: _controller,
onSubmitted: _handleSubmitted,
);
FocusScope.of(context).requestFocus(_textNode);
return new RawKeyboardListener(
focusNode: _textNode,
onKey: (key) => handleKey(key.data),
child: _textField
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("Search Item")),
body: _buildTextComposer(),
);
}
}
推荐答案
您的使用以下类的实例同时为keydown和keyup事件调用回调:
Your callback is getting called for both keydown and keyup events with instances of following classes:
- RawKeyDownEvent
- RawKeyUpEvent
您可以将整个对象传递给handleKey,并根据对象的运行时类型进行过滤。例如
You can pass the whole object to handleKey, and filter based on runtime type of object. for example
handleKey(RawKeyEvent key) {
print("Event runtimeType is ${key.runtimeType}");
if(key.runtimeType.toString() == 'RawKeyDownEvent'){
RawKeyEventDataAndroid data = key.data as RawKeyEventDataAndroid;
String _keyCode;
_keyCode = data.keyCode.toString(); //keycode of key event (66 is return)
print("why does this run twice $_keyCode");
}
}
_buildTextComposer() {
TextField _textField = new TextField(
controller: _controller,
onSubmitted: _handleSubmitted,
);
FocusScope.of(context).requestFocus(_textNode);
return new RawKeyboardListener(
focusNode: _textNode,
onKey: handleKey,
child: _textField
);
}
如果仍然不能解决问题,请检查从handleKey方法记录的实际runtimeType,并通过这些过滤器。
If this still does not help, check actual runtimeTypes logged from handleKey method, and filter by those.
这篇关于Flutter RawKeyboardListener收听了两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!