Возвращение ключевого события на EditText
Как я могу обработать событие нажатия клавиши назад при наборе текста EditText? Когда отображается виртуальная клавиатура и пользователь нажимает клавишу назад, она скрывается. Я хочу обработать это событие, но установка OnKeyListener в EditText не помогает.
5 ответов
Спасибо, Рено. Это, кажется, работает, но мне удалось решить это по-другому.
Я переопределил onTeyPreIme EditText (int keyCode, событие KeyEvent). Этот метод перехватывает нажатия клавиш в IME. =D
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK &&
event.getAction() == KeyEvent.ACTION_UP) {
// do your stuff
return false;
}
return super.dispatchKeyEvent(event);
}
Это не работает?
edText.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
//check if the right key was pressed
if (keyCode == KeyEvent.KEYCODE_BACK)
{
return true;
}
}
return false;
}
});
РЕДАКТИРОВАТЬ:
Хорошо, это удручает. Android не отправляет события IME при закрытии клавиатуры qwerty. Это единственный способ обойти это. Я надеюсь, что это работает и для вас.
Я понятия не имею, почему это так, но OnKeyListener работает, если вы просто переопределяете onKeyPreIme в своем пользовательском EditText.
customEditText.setOnKeyListener((v, keyCode, event) -> {
if(event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
getPresenter().onBackPressed();
break;
}
}
return false;
});
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
return super.dispatchKeyEvent(event);
}
Ни один из других ответов не работал для меня в SearchView
Я, наконец, в конечном итоге с переопределением dispatchKeyEventPreIme(...)
метод в моем собственном представлении:
class ImeAwareSearchView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : SearchView(context, attrs, defStyleAttr) {
var onKeyEventPreImeListener: OnKeyEventPreImeListener? = null
override fun dispatchKeyEventPreIme(event: KeyEvent?): Boolean {
onKeyEventPreImeListener?.onPreImeKeyEvent()
return false
}
}
Слушатель выглядит так:
interface OnKeyEventPreImeListener {
fun onPreImeKeyEvent()
}
И я устанавливаю его во Fragment, чтобы скрыть строку поиска:
search_input.onKeyEventPreImeListener = object: OnKeyEventPreImeListener {
override fun onPreImeKeyEvent() {
hideSearchRow()
}
}
Обратите внимание, что dispatchKeyEventPreIme(...)
метод вызывается дважды, поэтому убедитесь, что вы не проводите свой персонал на мероприятии дважды.
Наконец, я могу сделать это с помощью этих 3 шагов:
1. Создание пользовательского класса EditText для обработки обратного нажатия:
public class CustomEditTextWithBackPressEvent extends androidx.appcompat.widget.AppCompatEditText {
private MyEditTextListener onBackPressListener;
public CustomEditTextWithBackPressEvent(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOnBackPressListener(MyEditTextListener onBackPressListener) {
this.onBackPressListener = onBackPressListener;
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK &&
event.getAction() == KeyEvent.ACTION_UP) {
//back button pressed
if (Objects.requireNonNull(ViewCompat.getRootWindowInsets(getRootView())).isVisible(WindowInsetsCompat.Type.ime())) {
//keyboard is open
onBackPressListener.callback();
}
return false;
}
return super.dispatchKeyEvent(event);
}
public interface MyEditTextListener {
void callback();
}
}
2. Замените ваш обычный EditText этим CustomEditTextWithBackPressEvent в XML.
<CustomEditTextWithBackPressEvent
android:id="@+id/etSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/search_hint"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1" />
3. Ручка обратного пресса:
binding.etSearch.setOnBackPressListener(() -> {
//handle back press when keyboard is open
});