HoverEventを制御する
|※エミュレータ環境では、USBマウスを接続出来ないため動作未検証の内容になります。
ICS(Android4.0)から、Viewに対するHover状態(マウスオーバー状態)を検知することが出来るようになりました。
Hover状態の検知とは、USBマウスなどのポインティングデバイスを接続した場合に表示されるカーソルが
Viewの上に乗っている状態がわかることです。
HoverEventを制御すると、画像イメージやボタンの上にカーソルが重なった時に、画像やボタンの色を変えるなど
以前よりもっとリッチなUIを作成できるようになります。
本エントリでは、APIDemosのHoverEventを取り扱ったサンプルコードを参考にしながら、
HoverEventの制御方法を紹介していきます。
画像はAPIDemoの Views → Hover Events のスクリーンショットです。
それでは、続きをどうぞ。
新しく追加されたメソッド
Hoverイベントを制御するため、ICSでは新たにViewクラスとMotionEventクラスに以下表のAPIが追加されました。
新たに追加されたAPIを使用することで、特定のViewへのカーソルのHover状態を制御できます。
新規追加されたメソッド | 概要 |
---|---|
ViewクラスのsetOnHoverListenerメソッド | HoverEventのリスナ登録を行う |
ViewクラスのonHoverメソッド | HoverEventのリスナーメソッド |
MotionEvent.ACTION_HOVER_ENTER | Hover状態の開始を表すアクション |
MotionEvent.ACTION_HOVER_MOVE | Hover状態の継続を表すアクション |
MotionEvent.ACTION_HOVER_EXIT | Hover状態の停止を表すアクション |
HoverEventの登録
ViewクラスのsetOnHoverListenerメソッドでリスナーを登録すると、
HoverEventの発生時に、ViewクラスのonHoverメソッドがコールされます。
onHoverメソッドは以下表の引数を持ちます。
引数 | 概要 |
---|---|
View v | HoverEventが起こったView |
MotionEvent event | Actionの情報や座標情報、デバイスIDなどを持つ |
ViewクラスのgetIdメソッドを利用することで対象のViewを判断し、
MotionEventクラスのgetActionメソッドにより取得できるAction状態毎に処理を振り分けることが可能になります。
それでは、APIDemosのサンプルのソースコードをみてみましょう。
APIDemosのサンプルでは、以下の処理を行っています。
- サンプル実行画面中央部の「Hover Here」部分のViewにHoverEventを設定する
- HoverEvent開始時から終了時までの間、TextViewにXY座標を表示する
1.サンプル実行画面中央部の「Hover Here」部分のViewにHoverEventのリスナーを設定する
setOnHoverListenerメソッドを利用して、HoverEventのリスナーを登録しています。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.hover); mMessageTextView = (TextView) findViewById(R.id.message); mInterceptCheckBox = (CheckBox) findViewById(R.id.intercept_checkbox); mInterceptor = (HoverInterceptorView) findViewById(R.id.interceptor); View container = findViewById(R.id.container); container.setOnHoverListener(new View.OnHoverListener() { @Override public boolean onHover(View v, MotionEvent event) { // .....省略
登録したHoverEventのリスナーの中で、HoverEventの状態ごとに処理を振り分けています。
2.HoverEvent開始時から終了時までの間、TextViewにXY座標を表示する
3つのHoverEventの状態ごとに処理を行うため、MotionEventクラスのgetActionメソッドで状態を取得し各々の処理に振り分けています。
public boolean onHover(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_HOVER_ENTER: mMessageTextView.setText(Hover.this.getResources().getString( R.string.hover_message_entered_at, event.getX(), event.getY())); break; case MotionEvent.ACTION_HOVER_MOVE: mMessageTextView.setText(Hover.this.getResources().getString( R.string.hover_message_moved_at, event.getX(), event.getY())); break; case MotionEvent.ACTION_HOVER_EXIT: mMessageTextView.setText(Hover.this.getResources().getString( R.string.hover_message_exited_at, event.getX(), event.getY())); break; } return false; }
ソースコード中2行目、7行目、12行目にもあるように、
HoverEventで取得できる状態には、「ACTION_HOVER_ENTER」「ACTION_HOVER_MOVE」「ACTION_HOVER_EXIT」の3つの状態があります。
3つの状態は以下図のように、Viewにカーソルが乗った所がENTER、View上をカーソルが移動している間がMOVE、Viewからカーソルが抜けた状態がEXITとなります。
最後にサンプルのソースコードを添付します。
APIDemos/com/example/android/apis/view/Hover.java
public class Hover extends Activity { private TextView mMessageTextView; private CheckBox mInterceptCheckBox; private HoverInterceptorView mInterceptor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.hover); mMessageTextView = (TextView) findViewById(R.id.message); mInterceptCheckBox = (CheckBox) findViewById(R.id.intercept_checkbox); mInterceptor = (HoverInterceptorView) findViewById(R.id.interceptor); View container = findViewById(R.id.container); container.setOnHoverListener(new View.OnHoverListener() { @Override public boolean onHover(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_HOVER_ENTER: mMessageTextView.setText(Hover.this.getResources().getString( R.string.hover_message_entered_at, event.getX(), event.getY())); break; case MotionEvent.ACTION_HOVER_MOVE: mMessageTextView.setText(Hover.this.getResources().getString( R.string.hover_message_moved_at, event.getX(), event.getY())); break; case MotionEvent.ACTION_HOVER_EXIT: mMessageTextView.setText(Hover.this.getResources().getString( R.string.hover_message_exited_at, event.getX(), event.getY())); break; } return false; } }); mInterceptCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mInterceptor.setInterceptHover(isChecked); } }); } }