首页 文章

Flutter RawKeyboardListener听了两次?

提问于
浏览
2

我想要实现的是在查看此小部件时, RawKeyboardListener 在未选择 TextField /焦点时立即开始收听 . 它运行 HandleKey function 来处理我想用 keyCode 做什么 .

我遇到的问题是第一次运行应用程序时, handleKey function 似乎运行了两次 . 因此,在下面的示例中,当我只输入1个键时,它将打印 why does this run twice $_keyCode TWICE . 我认为它会监听keyUp和keyDown . 我想要的结果是它只运行一次......

但是,当我选择TextField并使用模拟器键盘进行常规提交时,代码也能正常工作 .

我很难理解为什么它在与TextField交互后才出现问题 . 我觉得它需要某个地方 Futureawait ?但我不知道 .

请帮忙 .

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(),
        );
      }
    }

2 回答

  • 3

    使用以下类的实例调用keydown和keyup事件的回调:

    • RawKeyDownEvent

    • RawKeyUpEvent

    您可以将整个对象传递给handleKey,并根据对象的运行时类型进行过滤 . 例如

    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方法记录的实际runtimeTypes,并按这些方法进行筛选 .

  • 1

    你是对的 . RawKeyboardListener 侦听原始键盘事件 . 这意味着它向下和向下返回(或命名约定在触摸屏上的方式) . 知道你可以简单地创建一个if语句并只是完成一次事件:

    bool _tempKeyPressedOnce = false;
    if (!_tempKeyPressedOnce) {
        // do stuff
        _tempKeyPressedOnce = true;
    }
    

相关问题