虚拟键盘上的onKeyListener无法工作

24

我不明白为什么这段代码不起作用。只有退格键和回车键被检测到,没有检测到其他按键。我的设备是Nexus One。

我尝试重写activity的OnKeyDown方法,结果更糟糕了。唯一检测到的按钮是硬件返回按钮。

我看到有人建议使用TextWatcher和onTextChanged,虽然在某些情况下可能有效,但这并不是真正的解决办法。例如,如果文本框为空,你将无法检测到用户按下BackSpace(删除)键。 所以有什么想法呢?

        TextView txtInput = (TextView)findViewById(R.id.txtInput);
    txtInput.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            makeToast(keyCode + " key pressed");
            return true;
        }
    });

好的,我在这个问题上花了4个小时。似乎没有人有解决方案。一些人也建议使用OnKeyboardActionListener,但找不到任何使用示例。 - bobetko
在这里找到示例:http://developer.android.com/resources/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.html - bobetko
我不确定软键盘示例是否适用于我。我不想编写另一个输入法。我只想在屏幕上显示默认的输入法(通常是安卓键盘),并捕获任何按键。为什么这似乎是一项艰巨的任务?我感到很沮丧。 - bobetko
根据 https://developer.android.com/reference/android/view/View.OnKeyListener 上的文档 - “这仅对硬件键盘有用;软件输入法不必触发此侦听器。” - aaronvargas
6个回答

19

好的,我最终找到了实现我想要功能的方法,但这并不是Android值得自豪的地方。

我正在编写一个服务器/客户端应用,其中在客户端上我必须打开软键盘并发送按下的键(字符和DEL键)...每次按下键时,该字符都会发送到服务器。如果按下DEL键,我会向服务器发送序列{BS}。

为了做到这一点,我必须实现TextWatcher和onTextChange,这很有效,除了EditText为空且用户按下DEL键的情况外。由于EditText中没有变化,因此无法检测到DEL键是否被按下。

除了TextWatcher之外,我还必须实现onKeyListener并将其附加到我的EditText控件上。这个onKeyListener忽略软键盘上除DEL和RETURN以外的所有键。不确定为什么?可能是一个错误吗?

这是我的代码:

    TextView txtInput = (TextView)findViewById(R.id.txtInput);
    txtInput.addTextChangedListener(inputTextWatcher);

    txtInput.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            Log.d(TAG, keyCode + " character(code) to send");
            return false;
        }
    });

并且 TextWatcher....

private TextWatcher inputTextWatcher = new TextWatcher() {
    public void afterTextChanged(Editable s) { }
    public void beforeTextChanged(CharSequence s, int start, int count, int after)
        { }
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        Log.d(TAG, s.charAt(count-1) + " character to send");;          
    }
};

有些键盘似乎不发送onkeyup键码(例如,S3 / S4上的三星默认键盘),这确实很烦人。您必须通过观察文本更改来解决它... - kenyee
2
当没有字符时,用户按下后退键怎么办? - Arslan Anwar

4

你在这里犯了一个错误。
如果你处理了事件,应该return true。 如果您想要允许下一个接收器处理事件,则应return false
你总是返回true


谢谢澄清。我也试着返回false。看了一些资料后,我发现必须使用onKeyboardActionListener。我明天会花点时间研究。谢谢。 - bobetko

4
注意:在您的EditText中提到了inputtype。
<EditText android:id="@+id/select_category" 
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences|textAutoCorrect" >



edittext.setOnEditorActionListener(new OnEditorActionListener() {

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

                if ((actionId & EditorInfo.IME_MASK_ACTION) == EditorInfo.IME_ACTION_DONE) {
                    //do something here.
                    return true;
                }
                return false;
            }
        });

这个解决了我的最小化键盘问题。它是否可以像你的代码一样不使用imeOptions? - Goufalite

3

参考自:

http://developer.android.com/reference/android/view/View.OnKeyListener.html

View.OnKeyListener

类概述:当硬件按键事件分派到此视图时,用于调用回调函数的接口定义。在将按键事件传递给视图之前,将调用回调函数。这仅对硬件键盘有用;软件输入法没有义务触发此侦听器。

看起来OnKeyListener只设计用于HARDWARE键盘!


3

你尝试过使用特定的监听器子类来处理该视图吗?

我曾经遇到过一个EditText的类似问题。下面的代码可以解决:

private OnKeyListener keyListener = new EditText.OnKeyListener(){

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        EditText et = (EditText) v;
        Log.i("APPEVENT", "Key hit: "+ event);
        //...
        return false;
    }

};

但是如果我使用 View.OnKeyListener,我只记录了退格和回车键。对于 TextView,可能会出现类似的问题。也许子类键监听器对于给定的 View 子类更敏感。


-1
我们在 iPhone 上也遇到了 TextWatcher 问题——如果缓冲区为空,键盘就不会发送删除事件。我们通过预加载键盘缓冲区中的1000个字符来解决这个问题。幸运的是,我们的应用程序将编辑字段隐藏在键盘后面,因此这1000个字符不会被看到。虽然有些丑陋,但它确实有效(除非用户在输入任何数据之前连续按下1000次删除键!)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接