9

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.

Hari Krishnan
  • 5,992
  • 9
  • 37
  • 55

2 Answers2

1

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

Community
  • 1
  • 1
Nidhin Prathap
  • 696
  • 5
  • 15
  • I cannot get the correct coordinates since i have implemented zooming option in the imageview with a SimpleOnScaleGestureListener. I have a scaling factor mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); in the onScale(ScaleGestureDetector detector) method. – Hari Krishnan Mar 16 '16 at 07:15
  • ah sry didnt see that part in your question – Nidhin Prathap Mar 16 '16 at 07:16
  • 1
    "I cannot get the correct coordinates since i have implemented zooming option in the imageview" -- you will have to run the calculations yourself, then, to convert from the touch coordinate to the effective coordinate system of your scaled image. – CommonsWare Mar 19 '16 at 11:53
1

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.

Community
  • 1
  • 1
Daniele Segato
  • 12,314
  • 6
  • 62
  • 88
  • Ok. The only thing i can do here is some manual calculations, and i got it. I can find the distance between the point where the use touched and the line that i drawn. Anyway it will be very helpful if google implements something like path.onTouchListner(). :) . Thanks for the guidance. – Hari Krishnan Mar 23 '16 at 05:37
  • They can't do such a thing. It's a data structure. It's like having a Map object and wanting an onTouchListener on it :) – Daniele Segato Mar 23 '16 at 09:56