OnEditorActionListener を使って EditText への Enter キー入力やアクション入力をハンドルする
EditText
への Enter キー入力を検知して何か処理をしたい、ということを調べてみると、TextView.OnEditorActionListener
を TextView#setOnEditorActionListener
メソッド で設定すればよいというようなブログ記事がいくつか見つかる。
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { // ... 処理 ... return false; } });
- EditTextでソフトキーボードのイベントをハンドリングする
- EditTextでEnterが押されたらキーボードを閉じる
- EditTextで入力完了したら、ソフトキーボード閉じて処理を実行する
- EditTextでエンターキーを押した時にソフトウェアキーボードを閉じる
- OnEditorActionListenerでエンターキーの入力を感知する
- EditTextでEnterキー押下時のイベントを処理する
ただ、ここら辺の記事を読んでも (一番下の記事以外は) onEditorAction
メソッドの第 2 引数 actionId
が何であるかや、第 3 引数 event
が null
になりうることについての言及がなかったりして情報として不十分だったので、調べたことを書き残しておく。
TextView#setOnEditorActionListener
メソッドとは
Javadoc には次のように書かれている。
Set a special listener to be called when an action is performed on the text view. This will be called when the enter key is pressed, or when an action supplied to the IME is selected by the user.
TextView | Android Developers
すなわち、Enter キーが入力されたときや IME に提供されているアクションが選択されたときに呼ばれるコールバック処理を設定するものである。 アクションについては後述する。 コールバック処理は TextView.OnEditorActionListener#onEditorAction(TextView v, int actionId, KeyEvent event) メソッド として記述される。
引数の actionId
は、選択されたアクションを識別するための ID である。 Enter キー入力の場合は EditorInfo.IME_NULL
になる。
第 3 引数 event
には、Enter キー入力の場合にのみ null
でない値が渡される。
また、Enter キー入力の場合には、キーダウン時とキーアップ時の 2 回 onEditorAction
メソッドが呼ばれるようである。
アクションとは
IME に提供されるアクションについては、次のドキュメントに書かれている。
EditText
が複数行を受け付けない場合に、多くのソフトウェアキーボードでは Enter キーの代わりにアクションボタンが表示されるようである。 デフォルトでは 「Next」 や 「Done」 が表示される。 EditText
要素の android:imeOptions
属性を使って、「Next」 や 「Done」 ではなく 「Go」 や検索ボタンを表示させることもできる。
上で説明した TextView#setOnEditorActionListener
メソッドを使うことで、次のような感じでアクションをハンドルできる。
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { boolean handled = false; if (actionId == EditorInfo.IME_ACTION_DONE) { // ... なんかの処理 ... handled = true; } return handled; // このメソッド中でアクションを消化したら true を返す。 } });
IME については詳しくないのでわからないのだけれど、『Most soft input methods provide a user action button in the bottom corner』 って書かれているので、おそらく IME の実装次第ではアクションボタンが提供されないこともある気がする。
あと、当然ながらハードウェアキーボードしかない場合はユーザーがアクションを実行することはできない。
OnEditorActionListener#onEditorAction
メソッドについてのプラクティス
- Enter キー入力以外では、第 3 引数
event
がnull
になるので、気を付ける必要がある。 - ソフトウェアキーボードの Enter キー入力では
OnEditorActionListener#onEditorAction
メソッドが呼ばれないことがある。- 参考: android - onEditorAction() is not called after Enter key has been pressed on Jelly Bean emulator - Stack Overflow
- これも IME の実装次第だと思われる *2。 バグか仕様かは不明。
- キーイベントについて 『You should never rely on receiving key events for any key on a soft input method』 (Handling Keyboard Actions | Android Developers) ということが書かれているので、
OnEditorActionListener#onEditorAction
メソッドについてもハードウェアキーボードの Enter しか受け取れないつもりでコードを書いた方が良さそう。
- 結論として、「
EditText
での Enter 入力時に (改行させずに) 何か処理をするようにしたい」 という場合、次のようにすべきだと思われる。 *3EditText
要素のandroid:inputType
属性を設定し、複数行入力をできないようにする。EditText
要素のandroid:imeOptions
属性にactionNone
以外の値を設定し、IME にアクションを提供する。 (あるいは独自のアクションを指定するとか。)onEditorAction
メソッドでは、アクションを受け取った場合の処理 (ソフトウェアキーボード用) と Enter キー入力を受け取った場合 (ハードウェアキーボード用) の両方の処理を書いておく。- このとき、Enter キー入力については
onEditorAction
メソッドが 2 回 (action=ACTION_DOWN と action=ACTION_UP) 呼ばれる可能性を考慮してコードを書いた方が良さそう。 (どういう条件でそうなるかはわかってないけど、1 回しか呼ばれないこともあれば 2 回呼ばれることもあるっぽい。)
- このとき、Enter キー入力については
- IME の実装次第ではアクションボタンが表示されず、Enter キー入力では
onEditorAction
メソッドが呼ばれないということもありうると思うので、onEditorAction
メソッドが呼ばれなくても次に進むための方法をユーザーに与えておくべき。 (「検索」 ボタンを配置しておく、とか。)
挙動については確証がない部分もあるけど、上のような感じで実装すれば問題はないはず。
Android Pattern Cookbook マーケットで埋もれないための差別化戦略
- 作者: あんざいゆき
- 出版社/メーカー: インプレスジャパン
- 発売日: 2014/03/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (3件) を見る