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

时间:2012-07-02 20:56:32

标签: android android-edittext android-4.2-jelly-bean

我有一个编辑文本,在我的应用程序中用作搜索框。在我的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();
     }
}

6 个答案:

答案 0 :(得分:40)

结束为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();
    }
}

答案 1 :(得分:6)

我发现了我的"类似bug的行为"是由于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,返回键符号=&#34; URdone&#34;

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

onEditorAction可以多次调用。

  • KeyEvent = null,actionId = 0

    • 如果返回true,则 仍在中,键盘打开,onEditorAction不会再次被调用
    • 如果返回false,则onEditorAction被称为SECOND time:
  • 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,这将根据上述光标行为进行调用。

答案 2 :(得分: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"的版本

答案 3 :(得分:1)

值得注意的是,点击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;
}
});

答案 4 :(得分:1)

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

int ch_search(char array_to_search[], char char_to_search_for, int array_size)
{
    char *buffer = malloc(array_size + 1);
    // Add test here to check if malloc was succesful

    strncpy(buffer, array_to_search, array_size);
    buffer[array_size] = '\0';

    int count = 0;
    for (char *i = buffer; (i = strchr(i, char_to_search_for)) != NULL; i++) {
        count++;
    }
    free(buffer);
    return count;
}

在你的java代码中:

imeActionLabel="xxxx"
imeActionId = "6"

它会正常工作。

答案 5 :(得分:0)

对于任何enter事件,操作ID默认情况下都设置为0。

来自Android documentation

actionId int:动作的标识符。这将是您提供的标识符,如果由于按下Enter键而被调用,则将是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;
}