How do I correctly translate pixel coordinates to canvas coordinates in Android?

廉价感情. 提交于 2019-12-05 02:45:53
weakwire

If i understand correctly you have a canvas View inside surfaceview. If so try VIEW.getLeft() | getTop() that returns the left | top position of the view relative to it's parent.

float x= e.getX() - canvasView.getLeft();
float y= e.getY() - canvasView.getTop();

You might try using the MotionEvent.getRawX()/getRawY() methods instead of the getX()/getY().

// get the surfaceView's location on screen
int[] loc = new int[2];
surfaceView.getLocationOnScreen(loc);
// calculate delta
int left = e.getRawX()-loc[0];
int top = e.getRawY()-loc[1];

Well, you have the screen px from the display in x,y, and you can call the canvas px via:

Canvas c = new Canvas();
int cx = c.getWidth();
int cy = c.getHeight();
...
Display display = getWindowManager().getDefaultDisplay(); 
int sx = display.getWidth();
int sy = display.getHeight();

Then, you can do the math to map the screen touch view , with the given px in both the view and the screen.

canvasCoordX = p.x*((float)cx/(float)sx);
canvasCoordY = p.y*((float)cy/(float)sy);

See http://developer.android.com/reference/android/view/WindowManager.html for more info on the screen manager. I think it needs to be initialized inside an activity to work.

agreeingly-ascyphous

I recently came upon this problem while doing something very similiar and after some trial and error and lots of googling I ended up adapting this answer (https://stackoverflow.com/a/9945896/1131180) :

(e is a MotionEvent, so the best place to use this code would be in onTouch or onLongPress)

mClickCoords = new float[2];

//e is the motionevent that contains the screen touch we
//want to translate into a canvas coordinate
mClickCoords[0] = e.getX();
mClickCoords[1] = e.getY();

Matrix matrix = new Matrix();
matrix.set(getMatrix());

//this is where you apply any translations/scaling/rotation etc.
//Typically you want to apply the same adjustments that you apply
//in your onDraw().

matrix.preTranslate(mVirtualX, mVirtualY);
matrix.preScale(mScaleFactor, mScaleFactor, mPivotX, mPivotY);

// invert the matrix, creating the mapping from screen 
//coordinates to canvas coordinates
matrix.invert(matrix); 

//apply the mapping
matrix.mapPoints(mClickCoords);

//mClickCoords[0] is the canvas x coordinate and
//mClickCoords[1] is the y coordinate.

There are some obvious optimizations that can be applied here but I think it is more clear this way.

user3132884

if you are using scrolling, then the actual y on the canvas is

float y = event.getY() + arg0.getScrollY();
Stefan Stejsi Brankovic

What I do in these situations is just:

  1. put a listener on whatever View/ViewGroup whose coordinates you wanna get by click
  2. Make it store them locally
  3. Whoever wants to access them should just request them via helper method.

And translation is done...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!