2010年8月13日金曜日

MotionEventに関するメモ

ViewのTouchイベントやTrackballイベントでは、MotionEventクラスによってポインタの情報が与えられる。※XperiaにはTackballは無い

以下、 MotionEventについて調べたことのメモ。

マウスポインタには、メインとサブがある。
マルチタッチ対応はAPI Level 5以降のため、複数ポインタに関する記述はAPI Level 5以降でのみ有効。

ポインタのイベントは、ACTION~のイベントコードで表される。
複数ポインタが存在する場合、一部のイベントは、ACTION_POINTER~のイベントコードで表される。これは、UPやDOWNなど位置以外の情報は、イベントコードでしか通知できないためである。
(複数ポインタがある状態でACTION_UPが来ても、どのポインタがUPされたか判別できない。)

ポインタのイベントコードは、getAction()で取得する。
戻り値をACTION_MASKとandすることで、イベントコードを取得できる。
また、API Leve 8以降では、getActionMasked()を用いると、ACTION_MASKとのandを省略できる。
API Level 1~4では、ACTION_MASKが存在しない。その場合は、getAction()の戻り値をそのまま使用する。

複数ポインタが存在する場合は、ポインタにIndexが付与されている。
ACTION_POINTER~イベントでは、下記のいずれかでポインタIndexを取得する。
  • getActionIndex() ※API Leve 8以降
  • API Level 5~7:(getAction() & ACTION_POINTER_ID_MASK ) >> ACTION_POINTER_ID_SHIFT
  • API Leve 8以降:(getAction() & ACTION_POINTER_INDEX_MASK ) >> ACTION_POINTER_INDEX_SHIFT

マウスポインタの位置は、通知されたイベントコードに関わらず毎回更新されている。
そのため、*常に*全ポインタの位置が検査されるべきである。
ポインタ数は、0 <= n < getPointerCount()。
API Level 1~4では、ポインタは常に1つだけのため、getPointerCount()は存在しない。

getEventTime()では、イベントが生成された時間を取得できる。
戻り値のlongは、UNIX時間(1970最初からの経過ms)。

getEdgeFlags()では、今回のイベントでViewの描画領域の端と接触したかどうかを取得できる。
戻り値は上下左右を表すビットフラグの集合。

API Level 5以降では、過去のACTION_MOVEイベントも記憶している。
getHistorical~(pinterIndex, pos)で取得可能。
posは履歴のIndex。最新のposは、getHistorySize()-1。

API Level 5以降の一部の機種では、画面が押された際の圧力を取得できる。
プログラム上では、getPressure~で取得可能。
通常は 0(圧力無し) ~ 1(通常圧力) の範囲のfloatだが、機種によっては1以上を返す可能性もある。

API Level 5以降の一部の機種では、押された画面領域サイズを取得できる。
プログラム上では、getSize~で取得可能。

recycle()が実装されているが、ハンドラ側では呼ばない。
もし特殊な理由で残しておきたい場合は、
MotionEvent.obtain(MotionEvent)やMotionEvent.obtainNoHistory(MotionEvent)でコピーを作成できる。作成したコピーはrecycle()する必要がある。

0 件のコメント:

コメントを投稿