将touchListener添加到路径对象

Har*_*nan 9 android ontouchlistener android-canvas

我有一个画布,我设置了一条路径

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

canvas.drawPath(path,p);
Run Code Online (Sandbox Code Playgroud)

现在我想向这个路径对象实现一个触摸侦听器.

我在自定义ImageView上实现了缩放选项,并在此自定义ImageView的onDraw方法的画布上绘制了这些线条.所以我不能通过检查用户触摸的坐标来做到这一点.

我知道路径对象不是View Class的子节点,因此我无法在其中实现touchListner.但我真正需要的是类似的东西

path.setOnTouchListener(myTouchListner);
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何实现它?任何帮助表示赞赏.

Dan*_*ato 1

没有这样的事。Path 只是一个数据结构,你如何使用它(绘制、剪辑……)与它无关。触摸事件也是如此。

您只需要对触摸坐标进行一些数学计算即可。这是使用矩阵的二维变换。您可以在维基百科上阅读相关内容。

首先,您应该将触摸点映射到缩放/平移坐标,请查看此处此处此处

我没有测试过,但如果你有一个 ImageView 这个方法应该这样做:

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;
}
Run Code Online (Sandbox Code Playgroud)

我无法告诉您这是否对您来说是开箱即用的,因为我不知道您的路径有什么用途,我只能假设您使用它在图像上绘制。如果在绘制路径之前应用任何其他变换,则应使用应用于路径的变换。

如果您在画布上进行这些转换,您可以像这样提取矩阵:

Matrix matrix = canvas.getMatrix()
Run Code Online (Sandbox Code Playgroud)

另一种方法是将矩阵值提取到数组中并自己进行计算:

// 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);
Run Code Online (Sandbox Code Playgroud)
  • values[2]values[5]x,y变换后元素左上角的坐标,与缩放系数无关
  • values[0]values[4]分别是变换后元素的宽度和高度的缩放系数。如果您以相同的倍数缩放,则它们应该是相同的值。

当您最终将触摸点转换为坐标系时,您可以使用其他人在问题评论中建议的方法检查Path它是否在路径内。

if (path.contains(coordX, coordY)) {
  // inside
} else {
  // outside
}
Run Code Online (Sandbox Code Playgroud)

您是唯一一个知道您正在使用的代码以及如何在您的视图中转换路径坐标系的人,因此也是唯一一个知道如何正确将其转换回来的人。因此,不要将此答案视为插入代码。我只是给你指明了方向。打印一些触摸坐标/转换的日志可能有助于在开发时进行调试。

祝你好运。