もうちょっとイベント
前回のイベントの記事 に関して、書き残した部分があったのでちょっと補足を加える。
無名クラスからの、その無名クラスを包含する外部の値へのアクセス
アンドロイドに限らず、javaの無名クラス一般に言えることであるが、 無名クラスからその無名クラスを包含する外部の値にアクセスするための、ちょっとしたトピックをとりあげる。
無名クラスを定義している外部のメソッド内のローカル変数へのアクセス
無名クラス内のメソッドから、その無名クラスを定義している外部のメソッド内のローカル変数 へアクセスする事はできない。
例えば, 以下のコードでは29行目でView.OnClickListenerを継承する無名クラスのonClickメソッド内から、 その無名クラスを定義しているonCreateメソッド内のローカル変数tvにアクセスしようとしているため、 コンパイルエラーとなる。
このような場合の解決策として、変数tvをローカル変数としてではなくアウタークラスEventSample9のインスタンス変数として、定義し直すやり方がよくとられる。
しかし、変数tvをあくまでもonCreateメソッド内に隠蔽したい場合には、20行目のコードを以下のように変更してローカル変数を定数に変更する事で解決できる。
アウタークラスのインスタンスへのアクセス
無名クラス内のメソッドから、アウタークラスのインスタンスを使いたい場合がある。
例えば、無名クラス内のメソッドでウィジェットクラスのインスタンスを生成したい場合には、 アウタークラスのインスタンスにアクセスする必要が生じる。
しかし、無名クラスのメソッド内でのthisは無名クラス自身のインスタンスを指すため、以下のようなコードでは25行目でコンパイルエラーとなってしまう。
「アウタークラス名.this」を使うと、アウタークラスのインスタンスを指すことができるので、 上記25行目のコードを以下のように変更する事でこの問題を解決できる。
「アウタークラス名.this」は、無名クラス内からダイアログボックスを表示する際に、よく使われる。
イベントリスナーのメソッドの引数
イベントリスナーのメソッドの引数には、様々なイベントの情報が格納されている。
前回のタッチイベントの例では、タッチダウンとタッチアップで2回イベントが発生していたが、 タッチイベントがタッチダウン時のものか,タッチアップ時のものかは、 イベントリスナーのメソッドの引数の値で判断できる。
以下のようなプログラムを使って、EditTextウィジェットのキーイベントとタッチイベントの引数をログに出力して、 イベントリスナーのメソッドの引数に、どの様な情報が格納されているか調べてみよう。
EditTextにキー「a」を入力した後に、タッチイベントを発生させた場合の「logcat」ビューの表示を以下に示す。
このログ出力を見ると、キーイベントもタッチイベントと同様に、キーダウン時とキーアップ時で2回イベントが発生している事がわかる。
アップとダウンのどちらのイベントかどうかは、イベントメソッドの引数eventのgetActionメソッドの値を参照する事で判断できる。
入力されたキーの値は、keyCode変数に格納されている。
keyCode変数の値がどのキーにあたるかは KeyEventクラスの定数をみればわかる。
KeyEventクラスの定数がどのキーか、親切に図入りで解説されている方のページ( キーイベントに応答するには - 逆引きAndroid入門)があるので、これを参照するとわかりやすい。
タッチイベントについては、MotionEventクラスのリファレンスも参照。