获取相对于视图的触摸坐标(ScreenToClient等效?)

时间:2011-12-09 21:16:44

标签: java android

我有一个我在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方法之外,我似乎无法发现任何事情。

有没有人知道这方面有一个很好的解决方案,或者我只是要自己动手?

这似乎是一种可用的方法 - 这就是我要问的原因。

谢谢大家的时间。

编辑:我不太确定坐标是否已经相对于视图。我本可以发誓说坐标是绝对的,但经过一些修修补补 - 我的工作正如我所期望的那样......对不起那些吵闹的家伙。

3 个答案:

答案 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之前,即使指针位于视图之外,视图也会继续接收运动事件。

您确定侦听器已在右侧视图中注册吗?