Apr 30, 2011

Detect Multi-Touch Event

It's a testing app for multi-touch event, target API level 8, Android 2.2. In my test on Nexus One running 2.2.1, only two points can be recognized.

Detect Multi-Touch Event

package com.TestMultiTouch;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TestMultiTouch extends Activity {

//In this test, handle maximum of 2 pointer
final int MAX_POINT_CNT = 2;

String[] pointerAction = new String[MAX_POINT_CNT];
float[] x = new float[MAX_POINT_CNT];
float[] y = new float[MAX_POINT_CNT];
TextView currentPointer;
TextView pointerStatus_01, pointerStatus_02;
TextView textDistance;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout MainLayout = (LinearLayout)findViewById(R.id.mainlayout);
MainLayout.setOnTouchListener(OnTouchListener);

currentPointer = (TextView)findViewById(R.id.currentpointer);
pointerStatus_01 = (TextView)findViewById(R.id.pointstatus_01);
pointerStatus_02 = (TextView)findViewById(R.id.pointstatus_02);
textDistance = (TextView)findViewById(R.id.distance);
}

private View.OnTouchListener OnTouchListener
= new View.OnTouchListener(){

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// TODO Auto-generated method stub

int pointerIndex = ((motionEvent.getAction() & MotionEvent.ACTION_POINTER_ID_MASK)
>> MotionEvent.ACTION_POINTER_ID_SHIFT);
int pointerId = motionEvent.getPointerId(pointerIndex);
int action = (motionEvent.getAction() & MotionEvent.ACTION_MASK);
int pointCnt = motionEvent.getPointerCount();

if (pointCnt <= MAX_POINT_CNT){
if (pointerIndex <= MAX_POINT_CNT - 1){

for (int i = 0; i < pointCnt; i++) {
int id = motionEvent.getPointerId(i);
x[id] = (int)motionEvent.getX(i);
y[id] = (int)motionEvent.getY(i);
}

switch (action){
case MotionEvent.ACTION_DOWN:
pointerAction[pointerId] = "ACTION_DOWN";
break;
case MotionEvent.ACTION_POINTER_DOWN:
pointerAction[pointerId] = "ACTION_POINTER_DOWN";
break;
case MotionEvent.ACTION_MOVE:
pointerAction[pointerId] = "ACTION_MOVE";

int distance = (int) Math.sqrt(
(x[0] - x[1]) * (x[0] - x[1]) +
(y[0] - y[1]) * (y[0] - y[1]));
textDistance.setText("distance: " + String.valueOf(distance));

break;
case MotionEvent.ACTION_UP:
pointerAction[pointerId] = "ACTION_UP";
break;
case MotionEvent.ACTION_POINTER_UP:
pointerAction[pointerId] = "ACTION_POINTER_UP";
break;
case MotionEvent.ACTION_CANCEL:
pointerAction[pointerId] = "ACTION_CANCEL";
break;
default:
pointerAction[pointerId] = "Unknown!";
}

currentPointer.setText(
"action = " + pointerAction[pointerId] + "\n"
+ "pointerIndex = " + String.valueOf(pointerIndex) + "\n"
+ "pointerId = " + String.valueOf(pointerId) + "\n"
+ "getPointerCount() = " + motionEvent.getPointerCount() + "\n");

pointerStatus_01.setText("[0] : "
+ String.valueOf(x[0]) + " : "
+ String.valueOf(y[0]));

pointerStatus_02.setText("[1] : "
+ String.valueOf(x[1]) + " : "
+ String.valueOf(y[1]));
}
}

return true; //means event have been processed
}};
}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/mainlayout"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:id="@+id/currentpointer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/pointstatus_01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/pointstatus_02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/distance"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


Refer Android Document for more details about android.view.MotionEvent

Related Post:
- Detect Touch Event
- Detect Touch Event, test on Custom View
- Detect Multi-Touch Event, test on Custom View

4 comments:

  1. did this code will differentiate single touch and multi touch.

    ReplyDelete
  2. or this will detect only the multi touch. I need to do some action in single touch, some other action on double touch. Where I can differentiate in this code?

    ReplyDelete
  3. i have two images on either sides of the screen. If use double fingers I need to resixe the images and need to show some buttons in the middle. If i click on the images some other process has to be done. I use scale gesture to detect the scalefactor and resize and bring back to normal. but while doing this always the click on images fires. I need to differentiate them.

    ReplyDelete

Infolinks In Text Ads