How to implement a "Two Finger Drag" gesture on Android?

Adit Gupta picture Adit Gupta · Feb 11, 2013 · Viewed 18.9k times · Source

I am new to Android development and am working on an accessibility research project for blind people (Jelly Bean API level 17 project). I have been experimenting with some gestures and the Two-Finger-Drag gesture has been really tough to implement. The following image captures what I actually require quite well.

drag gesture

I want the blind user to drag two fingers across horizontally (anywhere on the screen) and he would obtain an Audio output of the text he/she typed in the EditText. Also according to the distance the two fingers travel while dragging, we output each word separately.(Example below)

Example: If the user types "Today is a good day" and drags his finger (x value) by (say) 10 units to Left we output "good day" but if he drags it say 20 units to Left we output "a good day", for 30 units to Left "is a good day" etc etc.

I stumbled across which seems to detect two-finger touch:

TouchEvent(MotionEvent event)

Also this tutorial on detecting multiple touches seems promising, but I need it to work for touch and drag which I am not sure can be implemented like this.

Any new suggestions to implement this or pointers to tutorials that can help would be great!

Thanks in advance, Adit

Answer

Adit Gupta picture Adit Gupta · Feb 14, 2013

Okay So thanks to Gabe here and numerous blogs on this, I have found a solution to my question!

First I initialized my variables in the "Activity" class

int GLOBAL_TOUCH_POSITION_X = 0;
int GLOBAL_TOUCH_CURRENT_POSITION_X = 0;

Next, Inside the onCreate():

//Two-Finger Drag Gesture detection
    RelativeLayout TextLoggerLayout = (RelativeLayout)findViewById(R.id.ActivityrView);
    TextLoggerLayout.setOnTouchListener(
            new RelativeLayout.OnTouchListener(){

                @Override
                public boolean onTouch(View v, MotionEvent m) {
                    handleTouch(m); 
                    return true;
                }

    });

Now define the function handleTouch(m) as follows, it outputs the current position of the "Two-finger-touch" along with the initial position of the touch:

void handleTouch(MotionEvent m){
    //Number of touches
    int pointerCount = m.getPointerCount();
    if(pointerCount == 2){
        int action = m.getActionMasked();
        int actionIndex = m.getActionIndex();
        String actionString;
        TextView tv = (TextView) findViewById(R.id.testDiffText);
        switch (action)
        {
            case MotionEvent.ACTION_DOWN:                   
                GLOBAL_TOUCH_POSITION_X = (int) m.getX(1);
                actionString = "DOWN"+" current "+GLOBAL_TOUCH_CURRENT_POSITION_X+" prev "+GLOBAL_TOUCH_POSITION_X;
                tv.setText(actionString);
                break;
            case MotionEvent.ACTION_UP:                 
                GLOBAL_TOUCH_CURRENT_POSITION_X = 0;
                actionString = "UP"+" current "+GLOBAL_TOUCH_CURRENT_POSITION_X+" prev "+GLOBAL_TOUCH_POSITION_X;
                tv.setText(actionString);  
                break;  
            case MotionEvent.ACTION_MOVE:
                GLOBAL_TOUCH_CURRENT_POSITION_X = (int) m.getX(1);
                int diff = GLOBAL_TOUCH_POSITION_X-GLOBAL_TOUCH_CURRENT_POSITION_X;
                actionString = "Diff "+diff+" current "+GLOBAL_TOUCH_CURRENT_POSITION_X+" prev "+GLOBAL_TOUCH_POSITION_X;
                tv.setText(actionString);                   
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                GLOBAL_TOUCH_POSITION_X = (int) m.getX(1);
                actionString = "DOWN"+" current "+GLOBAL_TOUCH_CURRENT_POSITION_X+" prev "+GLOBAL_TOUCH_POSITION_X;
                tv.setText(actionString);
                break;
            default:
                actionString = "";
        }

        pointerCount = 0;
    }
    else {
        GLOBAL_TOUCH_POSITION_X = 0;
        GLOBAL_TOUCH_CURRENT_POSITION_X = 0;
    }
}

There you have it! The "Two-finger-drag" gesture finally implemented. Looks, like I can wrte a tiny blog post on it as well!! :)