OnKeyListener не работает на виртуальной клавиатуре

Я не понимаю, почему этот фрагмент кода не работает. Обнаружены только клавиши возврата и возврата. Слушатель не срабатывает ни для какого другого ключа. Мое устройство - Nexus One.

Я попытался переопределить метод OnKeyDown и это еще хуже. Единственной обнаруженной кнопкой была кнопка возврата оборудования.

Я вижу вокруг предложения использовать TextWatcher и onTextChanged, хотя это может работать в некоторых случаях, это не настоящая работа. Например, если текстовое поле пуст, вы не обнаружите, что пользователь нажимает кнопку BackSpace (Удалить). Итак, какие-нибудь идеи?

        TextView txtInput = (TextView)findViewById(R.id.txtInput);
    txtInput.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            makeToast(keyCode + " key pressed");
            return true;
        }
    });

Ответы

Ответ 1

Ok. Я, наконец, понял, как делать то, что хочу, и я не горжусь Android для этого.

Я пишу сервер/клиентское приложение, где на клиенте мне нужно открыть SoftKeyboard и отправить нажатые клавиши (символы и клавишу DEL)... При каждом нажатии клавиши этот символ отправляется на сервер. Если нажата DEL, я отправляю последовательность {BS} на сервер.

Для этого мне пришлось реализовать TextWatcher и onTextChange, который хорошо работает, за исключением ситуации, когда EditText пуст, и пользователь нажимает клавишу DEL. Поскольку в EditText нет изменений, невозможно обнаружить, что нажата клавиша DEL.

В дополнение к TextWatcher мне пришлось реализовать onKeyListener, который я привязал к элементу управления EditText. Этот onKeyListener игнорирует все клавиши на SoftKeyboard, кроме DEL и RETURN. Не знаете почему? Может быть, ошибка?

Вот мой код:

    TextView txtInput = (TextView)findViewById(R.id.txtInput);
    txtInput.addTextChangedListener(inputTextWatcher);

    txtInput.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            Log.d(TAG, keyCode + " character(code) to send");
            return false;
        }
    });

и TextWatcher....

private TextWatcher inputTextWatcher = new TextWatcher() {
    public void afterTextChanged(Editable s) { }
    public void beforeTextChanged(CharSequence s, int start, int count, int after)
        { }
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        Log.d(TAG, s.charAt(count-1) + " character to send");;          
    }
};

Ответ 2

Вы сделали одну ошибку здесь. он должен return true, если вы обработали событие. Если вы хотите разрешить обработку события следующим приемником, return false
Вы всегда возвращаетесь к истине

Ответ 3

Примечание: имя ввода в вашем редакторе.

<EditText android:id="@+id/select_category" 
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences|textAutoCorrect" >



edittext.setOnEditorActionListener(new OnEditorActionListener() {

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

                if ((actionId & EditorInfo.IME_MASK_ACTION) == EditorInfo.IME_ACTION_DONE) {
                    //do something here.
                    return true;
                }
                return false;
            }
        });

Ответ 4

Пробовали ли вы использовать специальный подкласс для этого представления?

У меня была аналогичная проблема с EditText. Приведенный ниже код работал:

private OnKeyListener keyListener = new EditText.OnKeyListener(){

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        EditText et = (EditText) v;
        Log.i("APPEVENT", "Key hit: "+ event);
        //...
        return false;
    }

};

Но если я использовал View.OnKeyListener, я записываю только обратное пространство и вхожу. Это может быть аналогичная проблема с TextView. Возможно, слушатели ключевых слов подкласса чувствительны к большему количеству событий для данного подкласса View.

Ответ 5

У нас также была проблема с TextWatcher на iPhone - если буфер пуст, клавиатура не отправляет событие del. Мы работали над этим, предварительно загрузив буфер клавиатуры 1000 символами. К счастью, наше приложение скрыло поле редактирования за клавиатурой, поэтому 1000 символов не видны. Это уродливо, но он работает (если только пользователь не ударил 1000 удалений подряд до ввода каких-либо данных!)

Ответ 6

Ссылка от:

http://developer.android.com/reference/android/view/View.OnKeyListener.html

View.OnKeyListener

Обзор класса Определение интерфейса для обратного вызова, который будет вызываться при отправке события аппаратного ключа в это представление. Обратный вызов будет вызван до того, как ключевое событие будет передано представлению. Это полезно только для аппаратных клавиатур; программный метод ввода не обязан запускать этого слушателя.

Кажется, OnKeyListener был разработан только для аппаратных ключей!