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();
}
}
Ответы
Ответ 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;
}
});