LoginSignup
3
1

More than 5 years have passed since last update.

EditTextに対してOnKeyListenerをセットしたらキーボード操作ができなくなった

Posted at

事象

EditTextにOnKeyListenerをセットして、キーボードのEnterキーまたは端末の戻るボタンをクリックした際にViewModelで定義した入力完了処理を呼び出す実装をしていました。
しかし、実際にアプリを動かしてみるとEditTextで文字入力を始めようとしたところキーボードが全く反応しませんでした。

問題

下記が実際のコードです。

SampleFragment.kt
EditText(context).apply {
    setOnKeyListener { _, keyCode, keyEvent ->
        if ((keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) ||
            (keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK)
        ) viewModel.onCompleteEdit()
        return@setOnKeyListener true
    }
}

上記コードではsetOnKeyListener(View.OnKeyListener)の戻り値が常にtrueになっています。

ここからは理解が合っているか不安な部分ではありますが、、、
この実装のままだと全てのキーイベントをリスナー側で消費することになり、実際にそのキーが押された際の動作までイベントが届かないようになってしまいます。

解決策

if文に入れた条件以外のキーイベントは消費したくないので、if文に入った時とそれ以外で返却する値を変えました。

SampleFragment.kt
EditText(context).apply {
    setOnKeyListener { _, keyCode, keyEvent ->
        if ((keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) ||
            (keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK)
        ) {
            viewModel.onCompleteEdit()
            return@setOnKeyListener true
        }
        return@setOnKeyListener false
    }
}

上記の実装で無事にキーボードが反応するようになりました。

おまけ

このコードを書いていた時はエミュレータで開発していたのですが、エミュレータでは動いていたので実機で触るまで気付きませんでした。
実機とエミュレータだとキーボードの仕様が違うのでしょうか。
少し調べてみたところ、そもそもView.OnKeyListenerはハードウェアキーボードに対するイベントを通知するものであって、ソフトウェアキーボードのイベントが必ずしも通知されるとは限らないみたいです。
https://developer.android.com/reference/android/view/View.OnKeyListener

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1