onEditorAction()中的null keyevent和actionid = 0(Jelly Bean / Nexus 7)

我有一个编辑文本,在我的应用程序中用作搜索框。 在我的Nexus 7上的Jelly Bean中,当我在正在监听的文本框中输入内容并点击时,输入KeyEvent = null和ActionId = 0传递给onEditorAction()方法。 有人遇到过这种情况么? 我在想它可能是一个bug。

在下面的第二个if语句中,我得到一个空指针,因为actionId = 0和KeyEvent = null;

// Search field logic. @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { Log.d(TAG, "onEditorAction"); if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) return false; if (actionId == EditorInfo.IME_ACTION_SEARCH || event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { .....Do some stuff(); } } 

结束为KeyEvent添加空检查。 感谢commonsware指出这种情况发生在3.0+。 似乎更像是一种解决方法,然后是解决方案,但它确实有效。

 // Search field logic. @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { Log.d(TAG, "onEditorAction"); if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) { return false; } else if (actionId == EditorInfo.IME_ACTION_SEARCH || event == null || event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { .....Do some stuff(); } } 

我发现我的“类似bug的行为”是由于imeActionLabel使事情复杂化。 我只使用它,因为它在“ 文本字段指南”中被提及作为一种自定义返回键标签的方法。 以下是我在Lollipop测试的结果,

情况1:默认,返回键符号=结束角括号

  

onEditorAction被调用一次。

  • KeyEvent = null,actionId = 5 = EditorInfo.IME_ACTION_NEXT
    • 如果返回true,则光标保持在EditText中,键盘打开
    • 如果返回false,则光标移动到下一个可聚焦,必要时键盘打开

案例2: imeOptions ,返回键符号=复选标记

  

onEditorAction被调用一次。

  • KeyEvent = null,actionId = 6 = EditorInfo.IME_ACTION_DONE
    • 如果返回true,则光标保持在EditText中,键盘打开
    • 如果返回false,则光标保留在EditText中,键盘关闭

案例3: imeActionLabel ,返回键符号=“URdone”

  

onEditorAction可以被多次调用。

  • KeyEvent = null,actionId = 0

    • 如果返回true,则光标保留在EditText中,键盘打开 ,onEditorAction不再被调用
    • 如果返回false,则onEditorAction称为SECOND时间:
  • KeyEvent = KeyEvent.ACTION_DOWN ,actionId = 0

    • 如果返回false,则光标移动到下一个可聚焦,必要时键盘打开 ,第三次不调用onEditorAction
    • 如果返回true,则onEditorAction称为第三个时间:
  • KeyEvent = KeyEvent.ACTION_UP ,actionId = 0

    • 如果返回true,则光标保持在EditText中,键盘打开
    • 如果返回false,则光标移动到下一个可聚焦,必要时键盘打开

笔记:

我不确定actionId = 0是来自EditorInfo.IME_ACTION_UNSPECIFIED还是EditorInfo.IME_NULL

如果下一个可聚焦是不可编辑的,则返回键符号将变为左箭头。

您还可以使用setOnFocusChangeListener覆盖onFocusChange ,它将根据上面的游标行为进行调用。

除了KeyEvent.ACTION_UP我们还需要捕获KeyEvent.ACTION_DOWN 。 除非KeyEvent.ACTION_UP永远不会传递给EditText所以我们的onEditorAction不起作用。 例:

 @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { final boolean isEnterEvent = event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER; final boolean isEnterUpEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_UP; final boolean isEnterDownEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_DOWN; if (actionId == EditorInfo.IME_ACTION_DONE || isEnterUpEvent ) { // Do your action here performLogin(); return true; } else if (isEnterDownEvent) { // Capture this event to receive ACTION_UP return true; } else { // We do not care on other actions return false; } } 

您必须根据android:imeOptions="actionNext"替换EditorInfo.IME_ACTION_DONE以更正EditorInfo.IME_ACTION_DONE版本

值得注意的是,您可以通过单击Enter获得多个事件(取决于Android版本)。 一个用于KeyDown(KeyEvent.ACTION_DOWN),一个用于KeyUp(KeyEvent.ACTION_UP)。 当我忘记检查我是否意外启动了两个服务器调用相同的操作。

 searchBox.setOnEditorActionListener(new OnEditorActionListener() { // enter key in search box triggers search @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if ((event != null && event.getAction() == KeyEvent.ACTION_UP) || event==null) { onSearchButtonClicked(); } return true; } }); 

如果你自定义返回键,你不会发现真相。 您需要在布局中设置imeActionLabelimeActionId 。 如:

 imeActionLabel="xxxx" imeActionId = "6" 

在你的java代码中:

 @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) { doSomeThing(); return true; } return false; } 

它会工作正常。