草庐IT

android - DispatchKeyEvent 监听空格键被按下

coder 2023-12-09 原文

我正在开发一个 Android 项目,我需要检查何时按下空格键以便我可以执行某个功能。

问题是,它可以在模拟器上运行,但不能在我的实际设备上运行。我认为这可能是因为我的模拟器使用的是物理键盘,而不是屏幕上的虚拟键盘,但在实际设备上进行测试时,它使用的是虚拟键盘。

我正在尝试调度键事件

@Override
    public boolean dispatchKeyEvent(KeyEvent event)
    {
        
        if (event.getKeyCode() == KeyEvent.KEYCODE_SPACE
                && event.getAction() == KeyEvent.ACTION_UP)
        {
            QueryEditor queryEditor = (QueryEditor)getSupportFragmentManager().findFragmentById(R.id.fragment_queryEditor);
            queryEditor.formatQueryText();
            return true;
        }
        }

我也试过按下开键

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if (keyCode == KeyEvent.KEYCODE_BACK)
        {
            disconnectDatabase();
        }
        else if (keyCode == KeyEvent.KEYCODE_DEL)
        {
            QueryEditor queryEditor = (QueryEditor)getSupportFragmentManager().findFragmentById(R.id.fragment_queryEditor);
            queryEditor.formatQueryText();
        }
        
        return super.onKeyDown(keyCode, event);
    }

除非按下后退按钮,否则这些都不会被触发,但我需要空格键来触发事件。

更新

下面是我如何创建 QueryEditor Fragment 和创建事件处理程序的代码

@Override
    public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);
        
        iQueryEditor = (IQueryEditor)this;
        iErrorHandler = (IErrorHandler)this;
        
        txtQueryEditor = (EditText)getActivity().findViewById(R.id.query_txtQueryEditor);
        
        btnSubmitQuery = (ImageButton)getActivity().findViewById(R.id.query_btnPerformQuery);
        btnClearQuery = (ImageButton)getActivity().findViewById(R.id.query_btnDeleteQuery);
        
        txtQueryEditor.addTextChangedListener(new QueryTextChanged(getActivity(), txtQueryEditor, iQueryEditor));
        setDatabaseUsed();
        txtQueryEditor.setOnEditorActionListener(new OnEditorActionListener() {
            
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER))
                        || actionId == EditorInfo.IME_ACTION_DONE)
                {
                    executeQuery();
                    return true;
                }
                else if (event.getKeyCode() == KeyEvent.KEYCODE_SPACE && event.getAction() == KeyEvent.ACTION_UP)
                {
                    Toast.makeText(getActivity(), "Space Bar Pressed", Toast.LENGTH_SHORT).show();
                    return true;
                }
                return false;
            }
        });
        
        btnSubmitQuery.setOnClickListener(mBtnSubmitQueryListener);
        btnClearQuery.setOnClickListener(mBtnDeleteQueryListener);
    }

txtQueryEditor 是我尝试接收空格键事件的 EditText。

最佳答案

部分答案在于 KeyEvent API documentation :

As soft input methods can use multiple and inventive ways of inputting text, there is no guarantee that any key press on a soft keyboard will generate a key event: this is left to the IME's discretion, and in fact sending such events is discouraged. You should never rely on receiving KeyEvents for any key on a soft input method. In particular, the default software keyboard will never send any key event to any application targetting Jelly Bean or later, and will only send events for some presses of the delete and return keys to applications targetting Ice Cream Sandwich or earlier. Be aware that other software input methods may never send key events regardless of the version. Consider using editor actions like IME_ACTION_DONE if you need specific interaction with the software keyboard, as it gives more visibility to the user as to how your application will react to key presses.

这是一个comment由 Google 工程师留下:

The answer is quite simple. Applications should never rely on key events to manage user input. The reason for this is, it results in a very poor user experience.

To start with, there are too many cases where it does not work. It does not work appropriately for CJK languages. It does not work correctly with gesture input, or with voice input, or with toggle input, or any new inventive input method developers may come up with in the future. In fact, the only case where it works is for only restricted cases of the poorest input experience : a legacy hardware-keyboard-like input method, which is a poor fit for the mobile era.

This is why Android defines a rich API through which IMEs communicate to the applications. It is method agnostic and language agnostic, and all software input methods are implementing it. Applications are supposed to make use of this API, and using EditText is the simplest way of doing this (more on this below).

Please stop relying on legacy key events for text entry -- AT ALL. It is good to support them, but requiring them is bad for everyone. It breaks consistency, it locks some languages out of your app, and it forces users into a much poorer experience than they expect on Android. And as noted in comment #14, input methods are explicitly under no obligation at all to send key events, though some may choose to do it.

There are two simple ways of implementing the rich text input APIs. Both will require some of this is done in Java land. The first one is to simply use EditText. If your app needs to do its own rendering, you can either subclass it if that suits you, or make it hidden while you render any changes to the text. You could also use DynamicLayout and Editable to achieve the same effect. Another possibility is to implement directly the InputConnection API by extending BaseInputConnection, however this is a LOT of hard work and should generally only need to be done by applications that have very specific needs with regards to text edition, like an IDE or a word processor.

关于android - DispatchKeyEvent 监听空格键被按下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23618567/

有关android - DispatchKeyEvent 监听空格键被按下的更多相关文章

  1. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  2. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  3. ruby - 将 Ruby 中的字符串切成固定长度的字符串,忽略(不考虑/不管)新行或空格字符 - 2

    我有一个包含许多换行符和空格的字符串。我需要将它拆分成固定长度的子字符串。例如a="Thisissome\nText\nThisissometext"现在我想把它分成长度为17的字符串。所以现在它应该导致["Thisissome\nText","\nThisissometex","t"]评论:我的字符串可能包含任何字符(空格/单词等) 最佳答案 "Thisissome\nText\nThisissometext".scan(/.{1,17}/m)#=>["Thisissome\nText","\nThisissometex","t"

  4. ruby - 至少 2 个空格的正则表达式? - 2

    我需要忽略任何一个空格,并且应该匹配至少大于一个空格的空格..."MARYHADALITTLELAMB"我希望"MARY","HADALITTLE","LAMB" 最佳答案 空格匹配是\s,您可以在花括号中提供最小值和最大值。您也可以省略其中任何一个,如下所示:\s{2,}所以你的代码应该是这样的:"MARYHADALITTLELAMB".split(/\s{2,}/)Youcantestitonlinehere! 关于ruby-至少2个空格的正则表达式?,我们在StackOverflo

  5. ruby - 在 ruby​​ 中的字符串前后添加空格? - 2

    我想在随机字符串前后添加一个空格。我试过使用"Random_string".center(1,"")但它不起作用。谢谢 最佳答案 我发现这是最优雅的解决方案:padded_string="#{random_string}"走简单的路没有错。 关于ruby-在ruby​​中的字符串前后添加空格?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/3357897/

  6. ruby-on-rails - 在 Rails 中格式化没有空格的日期 - 2

    我使用的API返回日期为"20090320",即Y、m和d。我如何在rails中将其格式化为20-03-2009?提前致谢! 最佳答案 Date.strptime('20090320','%Y%m%d').strftime('%d-%m-%Y') 关于ruby-on-rails-在Rails中格式化没有空格的日期,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/21364460/

  7. ruby - 什么是 Ruby 正则表达式来匹配至少有一个句点且没有空格的字符串? - 2

    匹配至少有一个句点且没有空格的字符串的正则表达式是什么? 最佳答案 你可以使用这个:/^\S*\.\S*$/它是这样工作的:^您可以将\S替换为[^]以严格使用空格(而不是制表符等) 关于ruby-什么是Ruby正则表达式来匹配至少有一个句点且没有空格的字符串?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/3913436/

  8. ruby - 如何在 Cucumber 的功能名称中使用空格 - 2

    我正在使用Windows并尝试运行一个现有的功能包,该功能包最初是在MacOS上构建的,这允许他们通过使用带空格的"\"来解决问题。我正在使用Ruby2.2.3和Cucumber。功能名称包含空格,我无法更改它。我尝试使用""和''来绕过空白,但每次都有同样的问题。这是问题的一个例子。如果我运行:cucumberfeatures/'Namecontainingwhitespaces.feature'它工作正常。但是当我运行时:cucumber-pmy_profile和cucumber.yml包含:my_profile:features/'Namecontainingwhitespace

  9. ruby-on-rails - Rails 是否支持监听 UDP 套接字的简洁方式? - 2

    在Rails中,什么是集成更新模型某些元素的UDP监听过程的最佳方式(特别是它将向其中一个表添加行)。简单的答案似乎是在同一个进程中使用UDP套接字对象启动一个线程,但我什至不清楚我应该在哪里做适合Rails方式的事情。有没有一种巧妙的方法来开始收听UDP?具体来说,我希望能够编写一个UDPController并在每个数据报消息上调用一个特定的方法。理想情况下,我希望避免在UDP上使用HTTP(因为它会浪费一些在这种情况下非常宝贵的空间),但我完全控制消息格式,因此我可以为Rails提供它需要的任何信息。 最佳答案 Rails是一个

  10. ruby-on-rails - encode_www_form 将空格转换为 + 而不是 %20 - 2

    我正在尝试从使用RubyonRails的散列创建http参数,我尝试使用URI.encode_www_form(params),但这没有正确生成参数。下面是我的哈希值params['Name'.to_sym]='NiaKun'params['AddressLine1'.to_sym]='AddressOne'params['City'.to_sym]='CityName'这个方法把空格转成+,我要的是把空格转成%20我收到"Name=Nia+Kun&AddressLine1=Address+One&City=City+Name"但我需要将此空格转换为%20

随机推荐