태그:                     

원문 링크 : Multitouch and gesture detection part 1

원문 링크 : Multitouch and gesture detection part 2


In this little tutorial I’m going to show you how to detect multitouch event on an Activity screen.

First of all let’s create a class next to the Main activity that called MultitouchView. It extends View:

public class MultitouchView extends View {
	public MultitouchView(Context context) {
		super(context);
	}
}

It has only one consturctor that you must implement. You have to add those two another constructors, otherwise the touch handling will not work:

public MultitouchView(Context context, AttributeSet attrs, int defStyle) {
	super(context, attrs, defStyle);
}

public MultitouchView(Context context, AttributeSet attrs) {
	super(context, attrs);
}

Now let’s edit your main.xml. I’m going to add a new xml element that’s called
com.helloandroid.multitouchexample.MultitouchView. In this case com.helloandroid.multitouchexample is my application package name. MultitouchView is the class name of View that handle the touch events.
After this your main xml will look like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:orientation="vertical" >

<com.helloandroid.multitouchexample.MultitouchView
	android:id="@+id/touchView"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent" />

</LinearLayout>

We no need to modify the main activity of the application:

public class Main extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}
}

With the setContentView method you can set the main xml as your activity content layout.

Now go back to MultitouchView class and implement the method that catch the motionevents, called onTouchEvent.

@Override
public boolean onTouchEvent(MotionEvent event) {
	super.onTouchEvent(event);

	int action = event.getAction() & MotionEvent.ACTION_MASK;

	switch (action) {
	case MotionEvent.ACTION_DOWN: {
		Log.d("MultitouchExample","Action Down");
		break;
	}

	case MotionEvent.ACTION_MOVE: {
		Log.d("MultitouchExample","Action Move");
		break;
	}

	case MotionEvent.ACTION_POINTER_DOWN: {
		Log.d("MultitouchExample","Pointer Down");
	break;
	}

	case MotionEvent.ACTION_POINTER_UP: {
		Log.d("MultitouchExample","Pointer up");
		break;
	}

	case MotionEvent.ACTION_UP: {
		Log.d("Multitouch", "Action up");
		break;
	}
	}

	return true;
}

You can get the user action from the MotionEvent object. There are a lot of constant actions that you can use to implement your own algorythm with them.
ACTION_DOWN is called when the user’s first finger reaches the screen.
ACTION_MOVE is called when the user move his finger on screen.
ACTION_POINTER_DOWN is called when the user touches the screen with a second, third non-primary-finger. In the next tutorial we are going to use this action to handle the multi touch input.
When the user’s non primary finger leave the screen, ACTION_POINTER_UP is called.
At the time when the last finger leave the screen the ACTION_UP is called.

In my next tutorial I’m going to show you an example how to use System.currentTimeMillis() to detect swipe gesture with multitouch.

Handling multitouch
Create a boolean member variable in your MultitouchView class that stores the actual multitouch event. Name it isMultiTouch.

public class MultitouchView extends View {
	private boolean isMultiTouch = false;
{...}

The variable’s default value is false, because the basic touch event isn’t multitouch until the user touches the screen with a second, third non-primary-finger.

In my last tutorial I wrote, the ACTION_POINTER_DOWN action called, when the user touches the screen with a second finger.

case MotionEvent.ACTION_POINTER_DOWN:
{
	Log.e( "Multitouch", "Action pointer down" );
	isMultiTouch = true;
	break;
}

You have to set the isMultiTouch variable back to false when the ACTION_POINTER_UP action called. The bits in ACTION_POINTER_ID_MASK indicate which pointer changed.

Swipe detection
For swipe detection you have to set a minimal swipe lenght with a member (final) variable.

private static final int SWIPE_MIN_LENGHT = 100;

Lesser lenght may cause the system detects swipe gesture instead of point action. Longer lenght may cause the system detects point gesture instead of swipe action. I think 100 is a good choice.

Multitouch detection by time
If you want to detect swipe gesture with multitouch the above example isn’t good, because you must touch the screen with the same time and that is hard. I set a minimal time interval thats handles the time between the first and the second finger touch the screen. You have to create long a variable to store the first finger’s touch time in ms.

private static final long MULTITOUCH_DELAY& = 500;
private long mTouchStart;

500 ms is enough time to touch with the second finger.

case MotionEvent.ACTION_DOWN:
{
	mTouchStart = System.currentTimeMillis();
	break;
}

Set the value when ACTION_DOWN called.
Now calculate with those two variables the multitouch value.

case MotionEvent.ACTION_POINTER_DOWN:
{
	Log.e( "Multitouch", "Action pointer down" );
	isMultiTouch = (mTouchStart - System.currentTimeMillis()) < MULTITOUCH_DELAY;
	break;
}

Within a half seconds the application wait for a non primary finger’s touch.

That’s it, feel free to comment.

관련글

[펌] Multitouch and gesture detection

답글 남기기

이메일 주소는 공개되지 않습니다.