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

syl*_*ism 18 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;
    }
};
Run Code Online (Sandbox Code Playgroud)

但是,这些是绝对坐标.我真正需要的是一个将其转换为相对于View的坐标的函数.

我做了一些挖掘,但除了我试图自己实现ScreenToClient方法之外,我似乎无法发现任何东西.

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

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

谢谢大家的时间.

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

Dee*_*eeV 26

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

如果您想获得触摸视图的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;
    }
};
Run Code Online (Sandbox Code Playgroud)

这样,如果用户在屏幕下方触摸40 x像素,但左边距设置为10,那么viewX将为30.如果您将视图向下移动40 x像素并且用户触摸了视图中的相同位置,它仍然是30.

如果你将padding包含在视图中仍然算作视图的填充,即使它没有显示任何内容,它也会稍微复杂一些.

编辑:

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

  • 嗯,我找到了一种方法:使用View.getLocationOnScreen()和/或getLocationInWindow(). (5认同)

DNa*_*Nax 22

我遇到了同样的问题,尝试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);
}
Run Code Online (Sandbox Code Playgroud)