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

2022-09-02 05:20:08

我有一个图像,我正在向我的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方法。

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

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

谢谢大家抽出宝贵时间。

编辑:我不太确定坐标是否已经相对于视图。我本可以发誓坐标是绝对的,但经过一些修补 - 我有事情按照我的预期工作。对不起噪音的家伙。


答案 1

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

如果要获取触摸视图相对于其自身的 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,则为30。如果将视图向下移动 40 x 像素,并且用户触摸视图中的同一点,则该点仍为 30。viewX

如果包含填充,则会稍微复杂一些,因为视图中的填充仍算作视图,即使它不显示任何内容。

编辑:

我应该指出,皮埃尔所说的是真的。如果触摸视图,则它将继续接收触摸事件,直到手指抬起,即使您将手指拖到视图边界之外也是如此。这意味着,ACTION_UP可以接收不在边界内的视图的触摸坐标。


答案 2

我刚刚遇到了同样的问题,尝试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);
}

推荐