Get Touch Coordinates Relative To A View (ScreenToClient Equivalent?)

前端 未结 3 1572
悲哀的现实
悲哀的现实 2021-02-01 20:09

I have an image I am displaying to a user in my android application.

I want to be able to tell where they \'touch\' the image.

I can easily get the screen coordi

相关标签:
3条回答
  • 2021-02-01 20:26

    I have just had the same problem, and trying the DeeV solution I always got 0 from both getLeft() and getTop() methods. As changing the layout wasn't an option (because I think that getTop/Left are relative only to the view's parent) I had to figure out how to get the absolute position of the view.

    Here is a similar approach using 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);
    }
    
    0 讨论(0)
  • 2021-02-01 20:34

    Touch Event coordinates are relative to the View that receives the event. However they are not limited to the View's size as the user can obviously slide outside the view in the same motion.

    Until an ACTION_UP or ACTION_CANCEL is triggered, the view will continue to receive the motion events even if the pointer is outside the view.

    Are you sure the listener is registered in the right View?

    0 讨论(0)
  • 2021-02-01 20:48

    Just to answer, the touches are relative to view in a way. Yes, they are raw screen coordinates of the touch. However, since you register the touch event to the view itself, it will only fire if the user actually touches the view. That means, even though the screen coordinates are raw screen coordinates, they are within the bounds of the view itself.

    If you want to get the x/y coordinates of the touched view in relation to only itself, then you can subract the left coordinate with the screen coordinate and the top coordinate from the y coordinate like so:

    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;
        }
    };
    

    With that, if the user touched 40 x-pixels down the screen, but the left margin was set to 10, then viewX would be 30. If you moved the view down 40 x-pixels and the user touched the same spot in the view, it would still be 30.

    It gets slightly more complicated if you included padding as padding within a View still counts as a View even though it doesn't display anything.

    EDIT:

    I should point out that what Pierre said is true. If you touch a view, then it will continue to receive touch events until the finger is lifted even if you drag your finger outside the view bounds. This means, ACTION_UP can receive touch coordinates for your view that are not within the bounds.

    0 讨论(0)
提交回复
热议问题