Friday, May 9, 2014

Detect multi touch on custom View to draw icons on canvas

Last exercise show how to "Detect single touch on custom View to draw icon on canvas". It is now modified to detect multi touch, to display multi icons.


MyView.java
package com.example.androiddrawinview;

import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View {
 
 private ArrayList<xy> drawList;
 private float offsetX, offsetY;
 private boolean touching = false;
 private Bitmap bm;

 public MyView(Context context) {
  super(context);
  init();
 }

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

 public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  setMeasuredDimension(
   MeasureSpec.getSize(widthMeasureSpec),
   MeasureSpec.getSize(heightMeasureSpec));
 }
 
 private void init(){
  bm = BitmapFactory.decodeResource(
    getResources(),
    R.drawable.ic_launcher);
  offsetX = bm.getWidth()/2;
  offsetY = bm.getHeight()/2;
 }

 @Override
 protected void onDraw(Canvas canvas) {
  canvas.drawColor(Color.GRAY);
  if(touching){
   for(xy pt : drawList){
    canvas.drawBitmap(bm, 
     pt.getX()-offsetX, 
     pt.getY()-offsetY, 
     null);
   }
  }
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  
  int action = event.getAction() & MotionEvent.ACTION_MASK;
  switch(action){
  case MotionEvent.ACTION_MOVE:
  case MotionEvent.ACTION_DOWN:
   
   ArrayList<xy> touchList = new ArrayList<xy>();
   int pointerCount = event.getPointerCount();
   
   for(int i=0; i < pointerCount; i++){
    touchList.add(
     new xy(
      event.getX(i), 
      event.getY(i)));
   }
   drawList = touchList;
   touching = true;
   break;
  default:
   touching = false;
  }
  
  invalidate();
  return true;
 }
 
 class xy{
  float x;
  float y;
  
  public xy(float x, float y){
   this.x = x;
   this.y = y;
  }
  
  public float getX(){
   return x;
  }
  
  public float getY(){
   return y;
  }
 }
 
}

/res/layout/fragment_main.xml, MainActivity.java and /res/layout/activity_main.xml, refer to last exercise.

download filesDownload the files.

Related:
Cannot detect MotionEvent.ACTION_MOVE and ACTION_UP

No comments: