2015年3月1日日曜日

マルチタッチではMotionEvent.ACTION_MASKでマスクする


ScrollViewでマルチタッチを検出したくてScrollViewを継承したカスタムビューを作り、 onInterceptTouchEventにてMotionEvent.ACTION_POINTER_DOWNを待ち構えたが 何故かイベントがキャッチされない。 
調べてみたところ、マルチタッチの場合はMotionEventのactionの値をMotionEvent.ACTION_MASKで マスクしてやらなければいけないらしい。

ダメな書き方
 public boolean onInterceptTouchEvent(MotionEvent event) {
    int action = event.getAction();
    switch (action) {
        case MotionEvent.ACTION_POINTER_DOWN:
            Log.v(TAG, "Action_pointer_down");
            break;

        case MotionEvent.ACTION_POINTER_UP:
            Log.v(TAG, "Action_pointer_up");
            break;
    }
    return false;
}

正しい書き方
 public boolean onInterceptTouchEvent(MotionEvent event) {
    int action = event.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_POINTER_DOWN:
            Log.v(TAG, "Action_pointer_down");
            break;

        case MotionEvent.ACTION_POINTER_UP:
            Log.v(TAG, "Action_pointer_up");
            break;
    }
    return false;
}

なぜこんなことをしなければいけないかはAndroid Developerにちゃんと書いてあった。
It returns the masked action being performed, without including the pointer index bits.

つまり、actionの値にはポインターのインデックスを示すbitがあり、マスクしないとそこの値も含めた値になってしまうためそれぞれのアクションの条件値と異なってしまうということらしい。


0 件のコメント:

コメントを投稿