24

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

在下面的第二个 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();
     }
}
4

6 回答 6

43

最终添加了对 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();
    }
}
于 2012-07-04T14:56:38.780 回答
7

我发现我的“类似错误的行为”是由于imeActionLabel事情复杂化。我之所以使用它,是因为在Text Fields Guide中提到它是一种自定义返回键标签的方法。这是我在 Lollipop 中的测试结果,

案例1:默认,返回键符号=右尖括号

<EditText
    android:singleLine="true"
    android:inputType="textUri"/>

onEditorAction 被调用一次。

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

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

<EditText
    android:singleLine="true"
    android:inputType="textUri"
    android:imeOptions="actionDone"/>

onEditorAction 被调用一次。

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

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

<EditText
    android:singleLine="true"
    android:inputType="textUri"
    android:imeOptions="actionDone"
    android: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_UNSPECIFIEDEditorInfo.IME_NULL

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

您也可以使用setOnFocusChangeListenerto override onFocusChange,它将根据上述游标行为调用。

于 2016-04-20T19:29:03.277 回答
3

旁边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;
    }
}

您必须根据以下内容替换EditorInfo.IME_ACTION_DONE为正确的版本EditorInfo.IME_ACTION_android:imeOptions="actionNext"

于 2014-07-15T18:11:58.007 回答
2

值得注意的是,单击 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;
}
});
于 2012-09-30T11:05:12.680 回答
1

如果您自定义返回键,您不会发现真相。您需要在布局中设置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;
}

它会正常工作。

于 2018-03-23T10:27:01.360 回答
0

默认情况下,任何输入事件的操作 ID 都设置为 0。

Android 文档

actionId int:动作的标识符。这将是您提供的标识符,或者 EditorInfo#IME_NULL 如果由于按下回车键而被调用。

所以处理输入键事件的正确方法是:

@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_NULL) {
        // Handle return key here
        return true;
    }
    return false;
}
于 2020-03-13T14:47:08.240 回答