ウィジェットのイベント処理


Androidでウィジェット(Viewクラス)のイベントの処理をおこなうには、イベントリスナーと呼ばれるインターフェースをインプリメントしたクラスを作成して、 このクラスをウィジェットと結び付けます。

例えば、ウィジェットがクリックされた時に実行されるクリックイベントの処理を記述するには、 イベント処理を記述するクラスにView.OnClickListenerインターフェースをインプリメントして、 ViewクラスのsetOnClickListenerメソッドを使ってこのクラスと結び付けます。

以下に、その例を示します。

上記のプログラムでは、TextViewウィジェットがクリックされた時にonClickメソッドが呼び出され、 クリックされたTextViewクラスのオブジェクトの表示文字列を変更します。

イベント処理メソッドは通常、Viewクラスの引数を持ち、その値はイベントの発生源となったオブジェクトを指している。

この引数を利用する事で、異なるウィジェットからのイベントを一つのイベント処理メソッドで、処理する事ができるようになります。

 

Viewクラスを覗いてみると、OnClickListenerインターフェースは以下のように定義されています。

他のイベントについても、基本的には同じです。

無名クラスを使う。

上記のようなコードでも良いのですが、これではややコードの記述が冗長となるため、

javaの無名クラスを使って実装する方法がよくとられます。

無名クラスについては、favicon匿名クラス(無名クラス)とイベントリスナー - 愚鈍人を参照。

以下に、上記のプログラムを無名クラスを使って実装した例を示します。

アクティビティにインプリメントする。

また、アクティビティクラスにイベントリスナ-をインプリメントする方法もよくとられます。

以下に、その例を示します。

この場合には、setOnClickListenerの引数にthisを指定して、アクティビティクラス自身をイベントと結び付けます。

レイアウトファイルにイベントメソッド名を記述する。

xmlレイアウトファイルにメソッド名を記述する事により、ウィジェットとイベント処理メソッドを結びつける事もできます。

以下に、例を示します。

EventSample7.java

main.xml

strings.xml

android:onClick属性はViewクラスのタグで使えるらしいのだが、TextViewタグに対して記述してもコンパイルエラーとはならないが、クリックイベントは発生しなかった。

Viewクラスを継承したクラスでも、使えるウィジェットと使えないウィジェットがあるらしい。

もちろん、strings.xmlでメソッド名を定義せずにandroid:onClick属性に直接、記述してもかまわない。

イベントリスナーのいろいろ

Viewクラスのイベントリスナーには、以下のものがあります。

  • onClick()
  • onLongClick()
  • onFocusChange()
  • onKey()
  • onTouch()
  • onCreateContextMenu()
  • onCreateContextMenu()

ただ、すべてのウィジェット(Viewクラスを継承したクラス)で、上記のイベントが有効になわけではないようです。

例えば、TextViewクラスでは通常キー入力を受け付ける必要が無いので、 onKeyのイベントリスナ-を設定してみるとコンパイラーエラーにはなりませんがイベントは発生しませんでした。

各イベントの内容については、 Handling UI Events Android Developers を参照。

複数のイベントを処理するクラスの記述と、イベント処理メソッドのboolean型の戻り値

複数のイベントリスナーをインプリメントする事により、一つのクラスで複数のイベント処理をおこなう事ができます。

以下に、その例を示します。

このプログラムを実行してTextViewをタッチすると、TextViewに「クリック・イベントが発生しました。」と表示されるが、 「タッチ・イベントが発生しました。」と表示される事はありません。

Log出力を確認してみると、以下のように表示されている。

 

 

これは、タッチイベントが発生しているのだがその後に発生したクリックイベントにより、TextViewの表示が書きかえられてしまう事を示している。

タッチイベントが2回発生しているのは、タッチダウン時とタッチアップ時にそれぞれイベントが発生するためのようだ。

今度は、上記のプログラムの35行目のonTouchメソッドの戻り値をtrueに変更してみる。

この場合には、「タッチ・イベントが発生しました。」としか表示されない。

LogCatは、以下のようになっている。

 

 

クリックイベントが発生していない。

これは、イベントの種類によっては複数のイベントが発生するものがあり、そのようなイベントメソッドはboolean型の値を返すように定義されており、 trueを返すと次のイベントを処理しない仕組みになっている事による。

アクティビティのイベント

ウィジェットだけでなく、アクティビティにもイベントがある。

以下のプログラムを実行して、アプリケーションのタイトルバーの部分をクリックしたり,キーをおしたりすると、 TextViewの表示文字列が変更されるので、イベントが発生している事がわかる。

アクティビティには、他にもいくつかオーバライドできるイベントがある。

Viewクラスのイベントハンドラ

Viewクラスにも、デフォルトのイベントハンドラが定義されていて、 Viewクラスを継承したクラスを作成してこのイベントハンドラをオーバライトする事で、 独自のウィジェットのイベントをカスタマイズする事ができる。

Viewクラスのイベントハンドラには、以下のものある。

  • onKeyDown(int, KeyEvent)
  • onKeyUp(int, KeyEvent)
  • onTrackballEvent(MotionEvent)
  • onTouchEvent(MotionEvent)
  • onFocusChanged(boolean, int, Rect)

Viewクラスのイベントハンドラのプログラム例については、「グラフィックス(1)-Viewクラスへの描画」のリスト2 を参照して下さい。

その他

以下のメソッドとイベントとの関係も、「要チェックや」。

  • Activity.dispatchTouchEvent(MotionEvent)
  • ViewGroup.onInterceptTouchEvent(MotionEvent)
  • ViewParent.requestDisallowInterceptTouchEvent(boolean)
  • isFocusableInTouchMode()
  • isInTouchMode()
  • isFocusable()
  • setFocusable()
  • isFocusableInTouchMode()
  • setFocusableInTouchMode()
  • requestFocus()

 

AmazonのAndroid関連商品

 

ページのトップへ戻る