Search code examples
androidandroid-imageviewandroid-gridviewandroid-event

Get the real X/Y position of an onTouch Event


I know there are some similar topics that have been posted, but I couldn’t find a good solution for my problem.

I have a GridView which is filed with a custom ImageAdapter. Everything works fine, but whenever I click on an image contained in the GridView, I would like to move another Imageview at the click's position. However, the coordinates of the Event, that I take with event.getX() and event.getY(), don’t correspond to the click’s position.

I first thought of a problem of dp/px conversion, and I tried several solutions in this way but none of them worked. Then I tried to use the getXPrecision(), but I couldn’t make a working solution… Maybe there is another way?

I would like to make the correct position programmatically, without adding constants int, so my project will work on various phone and tablet, with different dp and resolutions.

EDIT : Here is a screenshot, where i clicked the 3rd cell of the first line, and setted the position of the pencil with getRawX() - getRawY(). As we can see, this is not the correct position, I want the red dot (imageview's center) to be positionned where i clicked.

The code used :

//getting the position of the onTouch event :

    GridView centre = (GridView) findViewById(R.id.gridView);
    adapter = new ImageAdapter(this, (dim * dim), tailleCell);
    centre.setAdapter(adapter);

    centre.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View view, MotionEvent event) {

            int X = (int)event.getRawX();
            int Y = (int)event.getRawY();
            animation(X, Y, etat);
            return false;
        }
    });`

//launching the animation (and setting position of the pencil) :

  private void animation(int posX, int posY, int etat)
  {
    final ImageView img;
    if(etat == 0)
    {
       img = (ImageView) findViewById(R.id.imageView);
    }
    else
    {
        img = (ImageView) findViewById(R.id.imageView2);
    }

    img.clearAnimation();
    img.setVisibility(View.VISIBLE);

    img.setX(posX);
    img.setY(posY);
    [...]
  }

EDIT 2 : ~Solution :

Jesus Molina Rodríguez De Vera's solution wasn't working as expected, but i managed to make a workable solution. I just changed my code in the Event Handler to adjust the image's position :

 int[] offset = new int[2];
 centre.getLocationOnScreen(offset);
 int Xoffset=offset[0];
 int Yoffset = offset[1];
 int X = (int)event.getRawX();
 int Y = (int)event.getRawY();
 animation(X-((int)Math.round(Xoffset/1.15)), Y-((int)Math.round(Yoffset/1.5)), etat);

Sorry for my bad English :)

Thanks for your help!


Solution

  • Try using getRawX() and getRawY() instead of getX and getY.

    Edit

    I think that i have found the problem.

    You are obtaining X and Y relative to the GridView top-left corner, not to the absolute screen coordinetes.

    What you can do is the following:

    int[] offset = new int[2];
    center.getLocationOnScreen(offset);
    int Xoffset=offset[0];
    int Yoffset = offset[1];
    
    private void animation(int posX, int posY, int etat){ 
    
    //...
    
    img.setX(posX+Xoffset);
    img.setY(posY+Yoffset);
    [...] 
    }
    

    This is supposed to set the the top-left corner of the ImageView in the selected point. In order to set the center in that point:

    int ivWidth = img.getWidth();
    int ivHeight = img.getHeight();
    
    private void animation(int posX, int posY, int etat){ 
    
    //...
    
    int[] finalPosition=new int[2];
    finalPosition[0] = posX+Xoffset-(ivWidth/2);
    finalPosition[1] = posY+Yoffset-(ivHeight/2);
    img.setX(finalPosition[0]);
    img.setY(finalPosition[1]);
    [...] 
    }
    

    I haven't try it but it should work.

    Edit 2

    Xoffset and Yoffset are only needed if you use getX()/getY() instead of getRawX()/getRawY()