Tutorial details

Handling single and multi touch on Android- Tutorial | App Code for Sale | Preview

Handling single and multi touch on Android- Tutorial | Android Tutorial

How to use the touch API in Android applications

Overview PAGE TOP

Lars Vogel

Version 1.2

Copyright © 2011, 2012, 2013 Lars Vogel

04.01.2013

ajf.JPG

Single and multi touch in Android

This tutorial describes how to use the touch API in Android applications.

1.1. Android touch basics PAGE TOP

The Android standard Views support touch. You can react tp touch events also in your custom Views and your activities.

The base class for touch support is the MotionEvent class which is passed to Views via the onTouchEvent() method. To react to touch events you override the onTouchEvent() method.

The MotionEvent class contains the touch related information.e.g. the number of pointers, the X/Y coordinates and size and pressue of each pointer.

To react to touch events in your custom views you override the onTouchEvent() method.

This method returns true if the touch event has been handled by the view.

To react to touch events in an activity register in the activity an OnTouchListener for the relevant Views. You can do this by searching for the Views via the findViewById() method and by registering an OnTouchListener object to them via the onTouchListener() method of the View.

1.2. Single touch PAGE TOP

If single input is used you can use the getX() and getY() methods to get the current position of the first finger.

Via the getAction() method you receive the action which was performed. The MotionEvent class provides the following constants to determine the action which was performed.

Table 1. Touch Events

ajf1.JPG

1.3. Multi touch PAGE TOP

Multi-touch is available since Android 2.0.

The getPointerCount() method on MotionEvent allows to determine the number of pointers on the device. To track the touch events from multiple pointers you have to use the MotionEvent.ACTIONMASK and the MotionEvent.ACTIONPOINTERINDEXMASK constants to identify the touch event and the ID of the pointer.

1.4. GestureDetectors PAGE TOP

Android provide the GestureDetector class which allow to consume MotionEvents and to create higher level gesture events to listeners.

For example the ScaleGestureDetector class allows to determine the predefined gesture of increasing and decreasing the size of the object via two fingers.

2. Prerequisites PAGE TOP

The following assumes that you have already basic knowledge in Android development.

3.1. Draw via touch PAGE TOP

We will demonstrate Singletouch with an custom View.

Create an Android project called com.vogella.android.touch.single with the activity called SingleTouchActivity.

Create the following SingleTouchEventView class which implements a View which supports single touch.

package de.vogella.android.touch.single;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class SingleTouchEventView extends View {
  private Paint paint = new Paint();
  private Path path = new Path();

  public SingleTouchEventView(Context context, AttributeSet attrs) {
    super(context, attrs);

    paint.setAntiAlias(true);
    paint.setStrokeWidth(6f);
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    canvas.drawPath(path, paint);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    float eventX = event.getX();
    float eventY = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
      path.moveTo(eventX, eventY);
      return true;
    case MotionEvent.ACTION_MOVE:
      path.lineTo(eventX, eventY);
      break;
    case MotionEvent.ACTION_UP:
      // nothing to do
      break;
    default:
      return false;
    }

    // Schedules a repaint.
    invalidate();
    return true;
  }
}

Add this view to your activity.

package de.vogella.android.touch.single;

import android.app.Activity;
import android.os.Bundle;

public class SingleTouchActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SingleTouchEventView(this, null));
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_single_touch, menu);
    return true;
  }
}

If you run your application you will be able to draw on the screen with your finger (or with the mouse in the emulator).

Change your coding so that you use a layout definition based on XML. Hint: to use your own view in an XML layout definition you have to use the full-qualified class name (class including package information).

3.2. Tracking PAGE TOP

Add code to your drawing example so that the current position of a finger is marked via a circle. To draw a circle you can use the addCircle(x, y, 50, Path.Direction.CW) method call on a Path or use the canvas element directly.

Make sure that only the current position is highlighted with a circle. The circle should appears as soon as the finger goes down and vanish once the finger goes up.

The result should look like the following.

tay.png

4. Exercise: Multitouch Example PAGE TOP

We will demonstrate multi touch via an example with an own View. Create an Android project called com.vogella.android.touch.multi with the activity called MultiTouchActivity.

Create the following MultiTouchEventView class.

package com.vogella.android.touch.multiple;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MultiTouchEventView extends View {
  private Paint paint = new Paint();
  private Path path = new Path();

  public MultiTouchEventView(Context context, AttributeSet attrs) {
    super(context, attrs);

    paint.setAntiAlias(true);
    paint.setStrokeWidth(6f);
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    canvas.drawPath(path, paint);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {


    int action = event.getAction();
    if (event.getPointerCount()>1){
      int actionEvent = action & MotionEvent.ACTION_MASK;
      int actionPointerId= action & MotionEvent.ACTION_POINTER_INDEX_MASK;

      // Find the index of the pointer
      int index = event.findPointerIndex(actionPointerId);

      // Gets its coordinates
      float eventX = event.getX(index);
      float eventY = event.getY(index);

      // TODO Do something with the data

    }

    // Schedules a repaint.
    invalidate();
    return true;
  }
}

Add this view to your activity.

package com.vogella.android.touch.multiple;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;

public class MultiTouchActivity extends Activity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new MultiTouchEventView(this, null));
  }

}

If you run your application you will be able to draw on the screen with your finger (or with the mouse in the emulator).

5. Tutorial: ScaleGestureDetector PAGE TOP

Create the Android project called de.vogella.android.touch.scaledetector with an Activity called ScaleDetectorTestActivity.

Create the following class.

package de.vogella.android.touch.scaledetector;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;

public class ImageViewWithZoom extends View {
  private Drawable image;
  private float scaleFactor = 1.0f;
  private ScaleGestureDetector scaleGestureDetector;

  public ImageViewWithZoom(Context context) {
    super(context);
    image = context.getResources().getDrawable(R.drawable.icon);
    setFocusable(true);
    image.setBounds(0, 0, image.getIntrinsicWidth(),
        image.getIntrinsicHeight());
    scaleGestureDetector = new ScaleGestureDetector(context,
        new ScaleListener());
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // Set the image bounderies
    canvas.save();
    canvas.scale(scaleFactor, scaleFactor);
    image.draw(canvas);
    canvas.restore();
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    scaleGestureDetector.onTouchEvent(event);
    invalidate();
    return true;
  }

  private class ScaleListener extends
      ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
      scaleFactor *= detector.getScaleFactor();

      // Don't let the object get too small or too large.
      scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 5.0f));

      invalidate();
      return true;
    }
  }
}

Add this View to your activity.

package de.vogella.android.touch.scaledetector;

import android.app.Activity;
import android.os.Bundle;

public class ScaleDetectorTestActivity extends Activity {

/** Called when the activity is first created. */

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new ImageViewWithZoom(this));
  }
}

If you run your application you should be able to shrink and enlarge the image via a multi-touch gesture (pitch zoom).

Reference PAGE TOP

http://www.vogella.com/articles/AndroidTouch/article.html

0 Comments Leave a comment

Please login in order to leave a comment.

Newest first
!

Sign-in to your Chupamobile Account.

The Easiest way to Launch your next App or Game.

Join Chupamobile and get instant access to thousands of ready made App and Game Templates.

Creating an account means you’re okay with Chupamobile’s Terms of Service and Privacy Policy.