Java 获取相对于视图的触摸坐标(屏幕到客户端等效物?)

Java 获取相对于视图的触摸坐标(屏幕到客户端等效物?),java,android,Java,Android,我在android应用程序中向用户显示了一个图像 我想知道他们在哪里“触摸”图像 通过实现OnTouchListener,我可以很容易地获得屏幕坐标 private OnTouchListener image_Listener = new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEv

我在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;
    }
};
然而,这些是绝对坐标。我真正需要的是一个函数,将其转换为相对于视图的坐标

我已经做了一些挖掘,但除了我自己尝试实现ScreenToClient方法之外,我似乎什么都找不到

有人知道解决这个问题的好办法吗,还是我必须自己动手

这似乎是一种可行的方法——这就是我为什么要问的原因

谢谢大家抽出时间


编辑:我不太确定坐标是否已经相对于视图。我本可以发誓坐标是绝对的,但经过一番修改后,我的工作和我预期的一样。。抱歉打扰了。触摸事件坐标是相对于接收事件的视图的。但是,它们并不局限于视图的大小,因为用户可以明显地以相同的动作滑出视图

在触发“ACTION_UP”或“ACTION_CANCEL”之前,视图将继续接收运动事件,即使指针位于视图之外


你确定听众在正确的视图中注册了吗?

回答一下,触碰在某种程度上是相对于视图的。是的,它们是触摸屏的原始屏幕坐标。但是,由于将触摸事件注册到视图本身,因此仅当用户实际触摸视图时才会触发。这意味着,即使屏幕坐标是原始屏幕坐标,它们也在视图本身的范围内

如果您只想获取触摸视图相对于自身的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可以接收不在边界内的视图的触摸坐标。

我刚刚遇到了相同的问题,尝试DeeV解决方案时,我总是从getLeft()和getTop()方法中得到0。由于更改布局不是一个选项(因为我认为getTop/Left仅与视图的父视图相关),因此我必须找出如何获得视图的绝对位置

下面是使用getLocationOnScreen(位置)的类似方法:


是的,我注册了右视图。。我让事情按我预期的那样进行。我只是让事情变得比需要的更困难。感谢您的回复。我认为“触摸事件坐标相对于视图…”是不正确的。例如,我在屏幕下方有一个大约2/3的按钮-连接到它上,点击它的中心会得到一个比按钮高度大得多的y坐标。QED。OTOH,我是通过Xamarin表单来实现的,所以完全有可能附件并没有实际连接到按钮上(这可能是Xamarin的错误)。我也提出了同样的问题。在本教程中,这些方法,例如view.getLeft()。“返回视图相对于其父视图的位置。”通常,对于复杂的布局,调查视图不是屏幕视图的直接子视图。因此,Deev提到的方法并不总是适用。有什么新想法吗?嗯,我找到了一种方法:使用View.getLocationOnScreen()和/或getLocationInWindow()。这一个有效,而
screenY-v.getTop()
不(至少对我而言)v.getTop()也不适用于我。有人知道为什么吗?@eliasbagley:v.getTop()是相对于v的父对象的,而screenY是相对于屏幕的。仅当父级转到屏幕顶部时,它才起作用。
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);
}