Как правильно перевести координаты пикселей в координаты холста в Android? - PullRequest
9 голосов
/ 28 июля 2011

Я фиксирую MotionEvent для длительного нажатия на Android SurfaceView с использованием GestureListener.Затем мне нужно перевести координаты MotionEvent в координаты холста, из которых я могу генерировать пользовательские координаты карты (не Google Maps).

Из того, что я прочитал, я беру, что MotionEvent e, e.getX() и e.getY() получают координаты пикселей.Как я могу преобразовать эти координаты в SurfaceView координаты холста?

Вот мой GestureListener для прослушивания для длинных щелчков:

/**
* Overrides touch gestures not handled by the default touch listener
*/
private class GestureListener extends GestureDetector.SimpleOnGestureListener {

  @Override
  public void onLongPress(MotionEvent e) {
     Point p = new Point();
     p.x =  (int) e.getX();
     p.y = (int) e.getY();
     //TODO translate p to canvas coordinates
  }
}

Заранее спасибо!

Редактировать: Связано ли это с размером экрана / разрешением / глубиной и объектом Rect холста?

Ответы [ 6 ]

8 голосов
/ 04 августа 2011

Вы можете попробовать использовать методы MotionEvent.getRawX()/getRawY() вместо 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];
5 голосов
/ 01 августа 2011

Итак, у вас есть экран px с дисплея в x, y, и вы можете вызвать холст px через:

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

Затем вы можете выполнить математику, чтобы отобразить сенсорный экран, с указанным пикселем как в виде, так и на экране.

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

См. http://developer.android.com/reference/android/view/WindowManager.html для получения дополнительной информации о диспетчере экрана. Я думаю, что это должно быть инициализировано внутри действия, чтобы работать.

4 голосов
/ 25 мая 2013

Я недавно столкнулся с этой проблемой, когда делал что-то очень похожее, и после некоторых проб и ошибок и большого количества поисков в Google, я в итоге адаптировал этот ответ (https://stackoverflow.com/a/9945896/1131180):

(например, MotionEvent, поэтому лучше всего использовать этот код в onTouch или 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.

Есть несколько очевидных оптимизаций, которые могут быть применены здесь, но я думаю, что это станет более понятным.

1 голос
/ 31 июля 2011

Если я правильно понимаю, у вас есть холст. Вид изнутри. Если так попробуйте VIEW.getLeft() | getTop(), который возвращает влево | верхняя позиция представления относительно его родителя.

float x= e.getX() - canvasView.getLeft();
float y= e.getY() - canvasView.getTop();
0 голосов
/ 11 апреля 2018

Что я делаю в этих ситуациях просто:

  1. поместите слушателя в любую View / ViewGroup, координаты которой вы хотите получить, нажав
  2. Заставьте их хранить их локально
  3. Тот, кто хочет получить к ним доступ, должен просто запросить их с помощью вспомогательного метода.

И перевод сделан ...

0 голосов
/ 01 марта 2014

если вы используете прокрутку, то фактическое значение y на холсте равно

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