web-dev-qa-db-ja.com

onKeyListenerが仮想キーボードで機能しない

このコードが機能しない理由がわかりません。バックスペースとリターンキーのみが検出されます。リスナーは他のキーに対して起動しません。私のデバイスはNexusOneです。

アクティビティのOnKeyDownメソッドをオーバーライドしようとしましたが、それはさらに悪いことです。検出されたボタンはハードウェアの戻るボタンだけでした。

TextWatcherとonTextChangedを使用するという提案が出回っていますが、それが機能する場合もありますが、実際の回避策ではありません。たとえば、テキストボックスが空の場合、ユーザーがBackSpace(Delete)ボタンを押したかどうかは検出されません。だから何かアイデア?

        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;
        }
    });
23
bobetko

OK。やっと自分のやりたいことを思いついたのですが、Androidを誇りに思っていません。

クライアントでSoftKeyboardを開き、押されたキー(文字とDELキー)を送信する必要があるサーバー/クライアントアプリケーションを書いています...キーが押されるたびに、その文字がサーバーに送信されます。 DELを押すと、シーケンス{BS}がサーバーに送信されます。

そのためには、EditTextが空でユーザーがDelキーを押した場合を除いて、適切に機能するTextWatcherとonTextChangeを実装する必要がありました。 EditTextに変更がないため、DELキーが押されたことを検出する方法はありません。

TextWatcherに加えて、EditTextコントロールにアタッチしたonKeyListenerを実装する必要がありました。このonKeyListenerは、DELとRETURNを除くSoftKeyboardのすべてのキーを無視します。理由がわかりませんか?たぶんバグ?

これが私のコードです:

    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");;          
    }
};
19
bobetko

ここで1つの間違いをしました。
そうすべき return true、イベントを処理した場合。 イベントを次のレシーバーで処理できるようにするreturn false
あなたは常に真を返しています

4

注:edittextでのinputtypeの言及。

<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;
            }
        });

そのビューに特定のリスナーサブクラスを使用してみましたか?

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サブクラスのより多くのイベントに敏感です。

2
Adam A.

参照元:

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

View.OnKeyListener

クラスの概要ハードウェアキーイベントがこのビューにディスパッチされたときに呼び出されるコールバックのインターフェイス定義。コールバックは、キーイベントがビューに渡される前に呼び出されます。これは、ハードウェアキーボードにのみ役立ちます。ソフトウェア入力方式には、このリスナーをトリガーする義務はありません。

OnKeyListenerはハードウェアキー専用に設計されたようです!

IPhoneでもTextWatcherの問題が発生しました。バッファが空の場合、キーボードはdelイベントを送信しません。キーボードバッファに1000文字をプリロードすることで回避しました。幸い、私たちのアプリは編集フィールドをキーボードの後ろに隠したので、1000文字は表示されません。それは醜いですが、それは機能します(ユーザーがデータを入力する前に連続して1000回の削除をヒットしない限り!)

0
user199395