Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding touchListener to path object

I have an canvas over which i set a path

Path path = new Path();
path.moveTo(1, 1);
path.lineTo(90, 1);
path.lineTo(90, 60);
path.lineTo(1, 60);

canvas.drawPath(path,p);

Now i want to implment a touch listener to this path object.

I have implemented zooming option on a custom ImageView and drawing this lines over a canvas in the onDraw method of this custom ImageView. So i cant do it by checking the coordinates where user have touched.

I know that the the path object is not a child of View Class and hence i cannot implement a touchListner in it. But the thing the that i exactly need is something like

path.setOnTouchListener(myTouchListner);

Does anyone have any idea about how to implement it? Any help is appreciated.

like image 592
Hari Krishnan Avatar asked Mar 08 '16 08:03

Hari Krishnan


2 Answers

There's no such thing. The Path is only a data structure, how you use it (draw, clip, ...) has nothing to do with it. And so are touch events.

You just need to do some math with the touching coordinates. It's a 2D transformation using a matrix. You can read about this on wikipedia.

First you should map the touch point to the zoomed / panned coordinates, have a look here, here and here.

I didn't tested but if you have an ImageView this method should do:

final float[] getPointerCoords(ImageView view, MotionEvent e)
{
    final int index = e.getActionIndex();
    final float[] coords = new float[] { e.getX(index), e.getY(index) };
    Matrix matrix = new Matrix();
    // invert compute the inverse transformation matrix
    view.getImageMatrix().invert(matrix);
    // this adjust the panning
    matrix.postTranslate(view.getScrollX(), view.getScrollY());
    // this apply the inverse transformation to your touch points
    // which should give you the coordinates on your imageview
    matrix.mapPoints(coords);
    return coords;
}

I can't tell you if this will work out of the box for you because I do not know what use of the Path you have, I can only assume you use it to draw on top of your image. If you apply any other transformation before drawing the path you should use the transformation applied to the path instead.

If you do those transformation on your canvas you can extract the matrix like this:

Matrix matrix = canvas.getMatrix()

Another route is to extract the matrix values into an array and do the computation yourself:

// Get the values of the matrix
// create this array in a field an reuse it for performances
float[] values = new float[9];
matrix.getValues(values);
  • values[2] and values[5] are the x,y coordinates of the top left corner of the transformed element, regardless of the zoom factor
  • values[0] and values[4] are the zoom factors for the transformed element's width and height respectively. If you zoom at the same factor, these should both be the same value.

When you finally converted your touch point into the Path coordinate system you can check if it's inside the Path using this method someone else already suggested in the comments of your question.

if (path.contains(coordX, coordY)) {
  // inside
} else {
  // outside
}

You are the only one knowing the code you are working with and thus how the Path coordinate system is transformed in your view and thus the only one who can know how to properly convert it back. So don't think of this answer as a drop-in code. I just pointed you in the direction. Might be helpful to print some log of the touch coordinate / conversion to debug it while you develop.

Good Luck.

like image 174
Daniele Segato Avatar answered Oct 12 '22 17:10

Daniele Segato


Can u over ride the onTouchEvent(). Find the coordinates you have touched, check if the coordinate matches with your path., if it does trigger your function..

Please check below for detail REFERENCE

like image 25
Nidhin Prathap Avatar answered Oct 12 '22 17:10

Nidhin Prathap