Возвращение ключевого события на 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
});
Другие вопросы по тегам