kalenpw
kalenpw

Reputation: 695

Android 2 finger touch triggering 1 finger touch as well as 2 finger touch

I have an issue in my app where I need to perform a different action based on if one fingers or two fingers are pressed down.

Currently I have the follow code:

    @Override
    public boolean onTouchEvent(MotionEvent event){
        int touchX = (int)event.getX();
        int touchY = (int)event.getY();
        int action = event.getActionMasked();

        //Multitouch
        if(event.getPointerCount() > 1 && action == MotionEvent.ACTION_POINTER_DOWN){
            System.out.println("2 Finger press");

            return true;
        }
        else if(action == MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_POINTER_DOWN){

            if(event.getPointerCount() == 1) {
                System.out.println("single finger down");
                invalidate();
                return true;
            }
        }

        return false;
    }

The issue I am having is when I press with 2 fingers, the multitouch part registers, and after that so does the single press.

I did some googling around on ways to fix that and that would be why I am checking on the single touch conditional that action != MotionEvent.ACTION_POINTER_DOWN which I thought would fix the issue. That didn't fix the issue hence I decided to check that event.getPointerCount() == 1, but unfortunately that still causes both lines to print when I press with 2 fingers.

To summarize I need to only call the 2 finger part when 2 fingers are pressed down and not both.

Upvotes: 2

Views: 2283

Answers (1)

homerman
homerman

Reputation: 3569

refer to the documentation on "Handling Multi-Touch Gestures". it details exactly what you're looking for.

in essence, each active pointer is assigned an ID when it makes contact with the screen. your solution will should take into account which IDs come into play and are removed by observing various action states.

something a little bit along these lines (but beware compatibility calls for methods like getActionIndex()):

UPDATED CODE SAMPLE

public class MotionActivity extends AppCompatActivity {

    private int primaryPointerId   = -1;
    private int secondaryPointerId = -1;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(new FrameLayout(this));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        int action = event.getActionMasked();

        switch(action) {
            case MotionEvent.ACTION_DOWN:
                primaryPointerId = event.getPointerId(0);

                Log.d(getClass().getName(), "Primary pointer ID == [" + primaryPointerId + "]");

                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                secondaryPointerId = event.getPointerId(event.getActionIndex());

                Log.d(getClass().getName(), "Secondary pointer ID == [" + secondaryPointerId + "]");

                break;

            case MotionEvent.ACTION_MOVE:
                if(primaryPointerId > -1 && secondaryPointerId > -1) {
                    Log.d(getClass().getName(), "Two-point touch...");
                } else {
                    Log.d(getClass().getName(), "One-point touch...");
                }

                break;

            case MotionEvent.ACTION_POINTER_UP:
                if(event.getPointerId(event.getActionIndex()) == primaryPointerId) {
                    primaryPointerId = secondaryPointerId;
                }

                secondaryPointerId = -1;

                break;

            case MotionEvent.ACTION_UP:
                primaryPointerId = -1;

                break;
        }

        return true;
    }
}

Upvotes: 5

Related Questions