Android: как зафиксировать событие длительного нажатия на программном вводе/клавиатуре?

Краткая версия вопроса: как я могу зафиксировать событие длительного нажатия на программном вводе/клавиатуре в Android?

Длинная версия: в приложении для Android у нас есть многострочный EditText, и мы хотим иметь следующее поведение: 1. По умолчанию отображается кнопка ГОТОВО, при нажатии на нее программный ввод/клавиатура закрывается. 2. Если пользователь долго нажимает кнопку DONE, ее поведение изменится на кнопку ENTER, и в EditText появится новая строка.

Для требования № 1 я использовал решение здесь: https://stackoverflow.com/a/12570003/4225326

Что касается требования № 2, у меня есть блокирующий вопрос: как зафиксировать событие длительного нажатия. Я установил onEditorActionListener, но захваченное событие равно null: http://developer.android.com/reference/android/widget/TextView.OnEditorActionListener.html Я искал документ, метод, связанный с длительным нажатием, предназначен для жесткой клавиатуры: http://developer.android.com/reference/android/view/View.html#onKeyLongPress(int, android. view.KeyEvent), я не могу найти его для программного ввода/клавиатуры.

Спасибо за изучение этого вопроса.


person Samuel Cai    schedule 12.12.2014    source источник
comment
Вы пытались добавить doneButton.setOnLongClickListener(new OnLongClickListener() {...});   -  person k3b    schedule 22.11.2016


Ответы (2)


Я не смог найти этот ответ сам, поэтому я вручную закодировал решение. Я использовал таймер для событий onPress() и onRelease() из KeyboardView.OnKeyboardActionListener. Вот важный код. Многие TRY/CATCH опущены для краткости. На английском языке при нажатии клавиши я запускаю таймер, который ожидает то же время, что и обычное ожидание события длинного щелчка (ViewConfiguration.getLongPressTimeout()), а затем выполняет событие длинного щелчка в исходном потоке. Последующие отпускания и нажатия клавиш могут отменить любой активный таймер.

public class MyIME
    extends InputMethodService
    implements KeyboardView.OnKeyboardActionListener {
    :
    :
    private Timer timerLongPress  = null;
    :
    :

    @Override
    public void onCreate() {
        super.onCreate();
        :
        :
        timerLongPress = new Timer();
        :
        :
    }

    @Override
    public void onRelease(final int primaryCode) {
        :
        :
        timerLongPress.cancel();
        :
        :
    }

    @Override
    public void onPress(final int primaryCode) {
        :
        :
        timerLongPress.cancel();
        :
        :
        timerLongPress = new Timer();

        timerLongPress.schedule(new TimerTask() {

            @Override
            public void run() {

                try {

                    Handler uiHandler = new Handler(Looper.getMainLooper());

                    Runnable runnable = new Runnable() {

                        @Override
                        public void run() {

                            try {

                                MyIME.this.onKeyLongPress(primaryCode);

                            } catch (Exception e) {
                                Log.e(MyIME.class.getSimpleName(), "uiHandler.run: " + e.getMessage(), e);
                            }

                        }
                    };

                    uiHandler.post(runnable);

                } catch (Exception e) {
                    Log.e(MyIME.class.getSimpleName(), "Timer.run: " + e.getMessage(), e);
                }
            }

        }, ViewConfiguration.getLongPressTimeout());
        :
        :
    }

    public void onKeyLongPress(int keyCode) {
        // Process long-click here
    }
person CrazyIvan1974    schedule 24.10.2016
comment
Я не уверен, что ваше решение будет работать так, как задумано. Согласно документации, onPress() вызывается перед onKey() один раз, а onRelease вызывается после onKey(). Это будет означать, что onKey будет выполнен несмотря ни на что. Если ваше решение реализовано, то для длительного нажатия будет выполняться как нормальное поведение клавиши, так и поведение длительного нажатия. - person flide; 31.12.2016
comment
Еще одна проблема, которую я могу визуализировать, - где я могу установить и как мне получить код долгого нажатия клавиши?. Это будет особенно проблематично, так как структура в xml не предусматривает таких сценариев. Любые комментарии? - person flide; 31.12.2016
comment
это, кажется, работает! единственная проблема заключается в том, что он не отменяет действие клавиши при коротком нажатии, которое отправляется при отпускании клавиши. исправил это, вернув true в классе, который переопределяет KeyboardView. - person Matthew Morrone; 17.11.2020

Создайте собственный класс Keyboard View, расширив класс KeyboardView. Переопределить метод onLongPress()

person Sagar Das    schedule 22.04.2018