我有一个我在Android应用程序中向用户显示的图像。
我希望能够分辨出他们“触摸”图像的位置。
我可以通过实现OnTouchListener
轻松获取屏幕坐标 private OnTouchListener image_Listener = new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
float x = event.getX();
float y = event.getY();
return true;
}
return false;
}
};
然而,这些是绝对坐标。我真正需要的是一个将其转换为相对于View的坐标的函数。
我已经做了一些挖掘,但除了我试图自己实现ScreenToClient方法之外,我似乎无法发现任何事情。
有没有人知道这方面有一个很好的解决方案,或者我只是要自己动手?
这似乎是一种可用的方法 - 这就是我要问的原因。
谢谢大家的时间。
编辑:我不太确定坐标是否已经相对于视图。我本可以发誓说坐标是绝对的,但经过一些修修补补 - 我的工作正如我所期望的那样......对不起那些吵闹的家伙。
答案 0 :(得分:24)
回答一下,接触与某种方式相关。是的,它们是触摸的原始屏幕坐标。但是,由于您将触摸事件注册到视图本身,因此只有在用户实际触摸视图时才会触发。这意味着,即使屏幕坐标是原始屏幕坐标,它们也在视图本身的范围内。
如果你想获得被触摸视图的x / y坐标仅与自身相关,那么你可以用屏幕坐标和y坐标的顶部坐标减去左坐标,如下所示:
private OnTouchListener image_Listener = new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
float screenX = event.getX();
float screenY = event.getY();
float viewX = screenX - v.getLeft();
float viewY = screenY - v.getTop();
return true;
}
return false;
}
};
这样,如果用户在屏幕下方触摸了40 x像素,但左边距设置为10,那么viewX
将为30.如果您将视图向下移动40 x像素并且用户在视图中触及相同的位置,它仍然是30。
如果你将填充包含在视图中仍然算作视图的填充,即使它没有显示任何内容,也会稍微复杂一些。
编辑:
我应该指出皮埃尔说的是真的。如果您触摸视图,则即使您将手指拖到视图边界之外,它也会继续接收触摸事件,直到手指抬起为止。这意味着,ACTION_UP可以接收视图中不在范围内的触摸坐标。
答案 1 :(得分:21)
我遇到了同样的问题,尝试DeeV解决方案我总是从getLeft()和getTop()方法得到0。由于改变布局不是一个选项(因为我认为getTop / Left只相对于视图的父级)我必须弄清楚如何获得视图的绝对位置。
以下是使用getLocationOnScreen(location)的类似方法:
protected Point getRelativePosition(View v, MotionEvent event) {
int[] location = new int[2];
v.getLocationOnScreen(location);
float screenX = event.getRawX();
float screenY = event.getRawY();
float viewX = screenX - location[0];
float viewY = screenY - location[1];
return new Point((int) viewX, (int) viewY);
}
答案 2 :(得分:3)
触摸事件坐标相对于接收事件的视图。但是它们不限于视图的大小,因为用户可以在同一动作中明显滑动到视图之外。
在触发ACTION_UP或ACTION_CANCEL之前,即使指针位于视图之外,视图也会继续接收运动事件。
您确定侦听器已在右侧视图中注册吗?