Null keyevent и actionid = 0 в onEditorAction() (Желе Bean/Nexus 7) - программирование

Null keyevent и actionid = 0 в onEditorAction() (Желе Bean/Nexus 7)

У меня есть текст редактирования, который функционирует как окно поиска в моем приложении. В желе Bean на моем Nexus 7, когда я ввожу что-то в текстовое поле, которое я слушаю, и нажмите Enter, введите 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();
     }
}
4b9b3361

Ответ 1

Закончено добавление нулевой проверки для 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();
    }
}

Ответ 2

Я обнаружил, что мое "подобное ошибкам поведение" объясняется тем, что imeActionLabel усложняет ситуацию. Я использовал его только потому, что он упоминался в "Текстовые поля" в качестве способа создания пользовательской метки ключа возврата. Вот результаты моих тестов в Lollipop,

Случай 1: по умолчанию, символ клавиши возврата = скобка закрытия угла

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

onEditorAction вызывается один раз.

  • KeyEvent = null, actionId = 5 = EditorInfo.IME_ACTION_NEXT
    • если return true, курсор остается в EditText, клавиатура открыта
    • если return false, курсор перемещается в следующий режим фокусировки, клавиатура открывается, если необходимо

Случай 2: imeOptions, символ возврата = флажок

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

onEditorAction вызывается один раз.

  • KeyEvent = null, actionId = 6 = EditorInfo.IME_ACTION_DONE
    • если return true, курсор остается в EditText, клавиатура открыта
    • если return false, курсор остается в EditText, клавиатура закрывается

Случай 3: imeActionLabel, символ ключа возврата = "URdone"

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

onEditorAction можно вызывать более одного раза.

  • KeyEvent = null, actionId = 0

    • если return true, курсор остается в EditText, клавиатура открыта, onEditorAction НЕ вызывается второй раз
    • если return false, onEditorAction называется SECOND time:
  • KeyEvent = KeyEvent.ACTION_DOWN, actionId = 0

    • если возвращает false, курсор перемещается к следующему сфокусированным, при необходимости открывая клавиатуру, onEditorAction НЕ вызывается в третий раз
    • если return true, onEditorAction называется THIRD time:
  • KeyEvent = KeyEvent.ACTION_UP, actionId = 0

    • если return true, курсор остается в EditText, клавиатура открыта
    • если возвращает false, курсор перемещается в следующий режим фокусировки, при необходимости открывать клавиатуру

ПРИМЕЧАНИЯ:

Я не уверен, что actionId = 0 от EditorInfo.IME_ACTION_UNSPECIFIED или EditorInfo.IME_NULL.

Если следующий настраиваемый является не редактируемым, символ клавиши возврата становится левой стрелкой.

Вы также можете использовать setOnFocusChangeListener для переопределения onFocusChange, который будет вызываться в соответствии с приведенным выше курсорным поведением.

Ответ 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"

Ответ 4

Возможно, стоит отметить, что вы можете получить более одного события для нажатия 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;
}
});